2012-02-14 1 views
0

私はOpenRasta 2.0.3.0を使用しています。コレクションリソースのポストハンドラメソッドをオーバーロード

私は、ListOfActivityと呼ばれるコレクションリソースと、2つの異なるタイプのアクティビティ、FileUploadActivityCommentActivityを持っています。両方のアクティビティクラスはActivityBaseから継承されます。

チケット{ticketId}¥activitiesにGETリクエストを発行すると、ListOfActivityに戻ります。私はコレクションにアイテムを追加するために同じURIにどちらかの種類のアクティビティをPOSTできるようにしたいと思いますが、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(); 

私がしようとするとPOST 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だとして、私は一種の疑いがあるとして)、それは動作しません。

2つ目のアクティビティリソースが導入される前は、1つのpostメソッドが正常に解決されました。

ここで何か問題がありますか? this questionへのSebastien Lamblaの答えは、可能でなければならないことを示しているようです。

答えて

0

あなたはそれを行うことはできません。それは単なる悪事です。

URIはリソース登録全体で決して再使用しないでください。ORはひどく混乱し、論理的な決定はもうできません(これらの条件に警告/エラーを追加する必要があります)。

私はまず、リソースの種類でリソースの種類を宣言します。ここでは「活動のリスト」なので、です。 OpenRastaがあなたの方法を見ていきますとき

ResourceSpace.Has 
    .ResourcesOfType<ListOfActivity>() 
    .AtUri("tickets/{ticketId}/activities") 
    .HandledBy<ActivityHandler>() 
    .AsXmlSerializer(); 

、それは試してみて、正しい型に種類をdeserialzieことができる何かを見つけるでしょう。ここでは、それらが基本クラスを共有し、OpenRastaは本当にクールなフレームワークなので、独自の識別子(uris)を与えることなく、型自体をリソースに関連付けるだけでよいのです。あなたが活動のリストにあなたのPOSTを行う、またはHTTP要求(ここではポストのもの)と一致するすべてのメソッドを見つけ、それぞれに要求をdeserialieしようと、あなたのハンドラを見ていきます今

ResourceSpace.Has 
    .ResourcesOfType<ActivityBase>() 
    .WithoutUri 
    .AsXmlSerializer() 

最後に入力が最も多いメソッドを選択しました。

これは、ORが両方のメソッドに対して逆シリアル化を試みる可能性があることを意味しています。つまり、シーク可能なリクエスト(つまり、HttpListenerのデフォルトではなくasp.netのデフォルト)が必要です。あなたは少なくともそれが問題であるかもしれないことに気付いていなければなりません(チケット/ {ticketId} /コメントと.../fileUploadsなどを持つように)これを避けるために、登録を独立して分割します。

URI名は、1つのURIの複数のURIを区別するためのもので、1つのURIの複数のURIではありません。

+0

私のアプローチで何かが間違っていると思われました。答えをまとめる時間をとってくれてありがとう。私が結んできたアプローチは、あなたが示唆したように別々のURIを持つことでしたが、単一のコレクションとして戻すために元のコレクションURIを保持していました。 –

関連する問題