[英]Overloading Post Handler Methods for a Collection Resource
我正在使用OpenRasta 2.0.3.0。
我有一個名為ListOfActivity
的集合資源,以及兩種不同類型的活動, FileUploadActivity
和CommentActivity
。 這兩個活動類都從ActivityBase
繼承。
如果我向ticket {ticketId] \\ activities發出GET請求,那么我會返回ListOfActivity
。 我希望能夠將任何一種活動發布到相同的URI,以將項目添加到集合中,但是我很難讓OpenRasta解決處理程序上的適當方法。
我的(簡化的)處理程序實現是:
public class ActivityHandler : ServiceBase, IActivityHandler
{
public ListOfActivityResource GetByTicketId(int ticketId)
{
...
}
public OperationResult Post(FileUploadActivity fileUploadActivity, int ticketId)
{
...
}
public OperationResult Post(CommentActivity commentActivity, int ticketId)
{
...
}
}
以下是資源類:
[XmlType(TypeName = "commentActivity")]
public class CommentActivity : ActivityBase
{
[XmlElement("comment")]
public string Comment { get; set; }
}
[XmlType(TypeName = "fileUploadActivity")]
public class FileUploadActivity : ActivityBase
{
[XmlElement("content")]
public string Content { get; set; }
}
public class ActivityBase
{
[XmlAttribute("id")]
public int Id { get; set; }
[XmlElement("when")]
public DateTime When { get; set; }
[XmlElement("who")]
public string Who { get; set; }
// this property name is purposefully not called 'TicketId' as it caused an
// issue with OpenRasta's magic URI <> method matching algorithm because the
// UriTemplate for activity resources contains a parameter of the same name
[XmlElement("ticketId")]
public int TicketIdValue { get; set; }
}
[XmlType(TypeName = "activities")]
[UriTemplate("tickets/{ticketId}/activities")]
public class ListOfActivity
{
public ListOfActivity()
{
this.Activities = new List<ActivityBase>();
}
[XmlElement("fileUpload", typeof(FileUploadActivity))]
[XmlElement("comment", typeof(CommentActivity))]
public List<ActivityBase> Activities { get; set; }
}
我的配置的摘要是:
ResourceSpace.Has
.ResourcesOfType<ListOfActivity>()
.AtUri("tickets/{ticketId}/activities")
.HandledBy<ActivityHandler>()
.AsXmlSerializer();
ResourceSpace.Has
.ResourcesOfType<FileUploadActivity>()
.AtUri("tickets/{ticketId}/activities")
.HandledBy<ActivityHandler>()
.AsXmlSerializer();
ResourceSpace.Has
.ResourcesOfType<CommentActivity>()
.AtUri("tickets/{ticketId}/activities")
.HandledBy<ActivityHandler>()
.AsXmlSerializer();
當我嘗試發布CommentActivity
,收到405響應。 這是我在日志中看到的內容:
Found 2 operation(s) with a matching name.
Found 0 operation(s) with matching [HttpOperation] attribute.
Operation ActivityHandler::Post(FileUploadActivity fileUploadActivity, Int32 ticketId) selected with 2 required members and 0 optional members, with codec XmlSerializerCodec with score 1.
Operation ActivityHandler::Post(FileUploadActivity fileUploadActivity, Int32 ticketId) selected with 2 required members and 0 optional members, with codec XmlSerializerCodec with score 1.
Operation ActivityHandler::Post(FileUploadActivity fileUploadActivity, Int32 ticketId) selected with 2 required members and 0 optional members, with codec XmlSerializerCodec with score 1.
Operation ActivityHandler::Post(CommentActivity commentActivity, Int32 ticketId) selected with 2 required members and 0 optional members, with codec XmlSerializerCodec with score 1.
Operation ActivityHandler::Post(CommentActivity commentActivity, Int32 ticketId) selected with 2 required members and 0 optional members, with codec XmlSerializerCodec with score 1.
Operation ActivityHandler::Post(CommentActivity commentActivity, Int32 ticketId) selected with 2 required members and 0 optional members, with codec XmlSerializerCodec with score 1.
Executing OperationResult OperationResult: type=MethodNotAllowed, statusCode=405.
No response codec was searched for. The response entity is null or a response codec is already set.
There was no response entity, not rendering.
Writing http headers.
我嘗試命名URI,並使用HttpOperationAttribute
,但是它不起作用(我有點懷疑,因為它們都是相同的URI)。
在引入第二種活動資源之前,可以很好地解決單一發布方法。
我在這里做錯什么了嗎? 塞巴斯蒂安·蘭布拉(Sebastien Lambla)對這個問題的回答似乎表明它應該是可能的。
你不能那樣做,那簡直就是邪惡。
絕對不要在資源注冊之間重用URI,否則,URI將會非常混亂,並且不再能夠做出邏輯決定(我們應該在這些條件下添加一些警告/錯誤)。
我首先用資源是聲明資源類型。 這是“活動列表”,因此我們將使用它 。
ResourceSpace.Has
.ResourcesOfType<ListOfActivity>()
.AtUri("tickets/{ticketId}/activities")
.HandledBy<ActivityHandler>()
.AsXmlSerializer();
當OpenRasta查看您的方法時,它將嘗試找到可以將類型反序列化為正確類型的內容。 在這里,由於它們共享一個基類,而OpenRasta是一個非常酷的框架,您只需要將類型本身與資源相關聯,而無需為其指定標識符(URI)。
ResourceSpace.Has
.ResourcesOfType<ActivityBase>()
.WithoutUri
.AsXmlSerializer()
現在,當您對活動列表進行POST時,或將查看您的處理程序,找到與http請求匹配的所有方法(此處為Post方法),並嘗試對每個請求中的請求進行反序列化,最后選擇該方法剩下的投入最多。
如果您了解這個概念,就會知道OR可能會嘗試對這兩種方法進行反序列化,這意味着您需要一個可搜索的請求(又名asp.net上的默認值,而不是HttpListener上的默認值)。 您至少需要意識到這一點,並且如果可能是一個問題,請獨立拆分注冊以避免這種情況(例如,具有tickets / {ticketId} / comments和... / fileUploads等)。
URI名稱用於區分一個資源的多個URI,而不是一個URI的多個資源(在OR中永遠無法使用)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.