0

OpenRasta ハンドラーで HTTP PUT を処理しているときに、非常に奇妙な動作が発生します。ハンドラー メソッドのシグネチャは次のようになります。

public CustomerResource Put(CustomerForm customerForm)

そして、ここに関連するResourceSpace構成があります:

ResourceSpace.Has.ResourcesOfType<CustomerListResource>()
    .AtUri("/customers")
    .HandledBy<CustomerHandler>()
    .RenderedByAspx("~/Views/Customer/CustomerListView.aspx")
    .And.AsJsonDataContract().ForMediaType("application/json;q=0.3")
    .And.AsXmlSerializer().ForMediaType("application/xml;q=0.2");

ResourceSpace.Has.ResourcesOfType<CustomerResource>()
    .AtUri("/customers/{id}")
    .HandledBy<CustomerHandler>()
    .RenderedByAspx("~/Views/Customer/CustomerEditView.aspx")
    .And.AsJsonDataContract().ForMediaType("application/json;q=0.3")
    .And.AsXmlSerializer().ForMediaType("application/xml;q=0.2");

// To support POST and PUT to /customers
ResourceSpace.Has.ResourcesOfType<CustomerForm>()
    .WithoutUri
    .RenderedByAspx("~/Views/Customer/CustomerEditView.aspx")
    .And.AsJsonDataContract().ForMediaType("application/json;q=0.3")
    .And.AsXmlSerializer().ForMediaType("application/xml;q=0.2");

CustomerForm次のようになります。

[XmlRoot("customer", Namespace = ClientSettings.Namespace)]
public class CustomerForm : FormBase, ICustomer
{
    [XmlElement("contact-info")]
    public ContactInfo ContactInfo { get; set; }

    [XmlAttribute("id")]
    public int Id { get; set; }
}

ContactInfo次のようになります。

[XmlRoot("contact-info", Namespace = ClientSettings.Namespace)]
public class ContactInfo
{
    [XmlElement("email")]
    public string Email{ get; set; }

    [XmlElement("first-name")]
    public string FirstName{ get; set; }

    [XmlElement("last-name")]
    public string LastName{ get; set; }

    [XmlElement("mobile-phone-number")]
    public string MobilePhoneNumber { get; set; }
}

私の問題はCustomerForm、サーバーに PUT するときに、OpenRasta が適切にデシリアライズできないことです。クライアントから正常に送信されますが、ContactInfoセットを使用してデシリアライズします。必要な XML が実際にそこにあることを確認するためにnullIRequest.Entity.Stream

<?xml version="1.0" encoding="utf-8"?>
<customer id="1" xmlns="urn:namespace">
    <contact-info>
        <email>5867ca8a5a5548428c4bc90c1f7e41d6@example.com</email>
        <first-name>0440a6d5f071478d8571bac1301552bc</first-name>
        <last-name>49069fb41eb141c79326dc64fa034573</last-name>
        <mobile-phone-number>59980075</mobile-phone-number>
    </contact-info>
</customer>

メソッドで受信しIRequest.Entity.Streamた逆シリアル化CustomerFormされたオブジェクトが含まれていないときに、必要なデータをどのように含めることができますか? Put(CustomerForm)シリアライゼーションとデシリアライゼーションが完全に機能することを確認するテストがありPost(CustomerForm)、まったく同じハンドラーでも機能します。に設定されCustomerFormているのは、HTTP メソッドが PUT のときだけです。ContactInfonull

私は OpenRasta からのデバッグ出力を徹底的に読みました。

    27-[2011-07-15 11:09:15Z] Information(0) Operation CustomerHandler::Put(CustomerForm customerForm) was selected with a codec score of 0
    27-[2011-07-15 11:09:15Z] Information(0) Loaded codec OpenRasta.Codecs.XmlSerializerCodec
    27-[2011-07-15 11:09:15Z] Verbose(0) Switching to full object media type reading.
27-[2011-07-15 11:09:15Z] Stop(1) Exiting PipelineRunner
27-[2011-07-15 11:09:15Z] Start(1) Entering PipelineRunner: Executing contributor OperationInterceptorContributor.WrapOperations
27-[2011-07-15 11:09:16Z] Stop(1) Exiting PipelineRunner
27-[2011-07-15 11:09:16Z] Start(1) Entering PipelineRunner: Executing contributor OperationInvokerContributor.ExecuteOperations
    27-[2011-07-15 11:09:16Z] Verbose(0) Ignoring constructor, following dependencies didn't have a registration:OpenRasta.OperationModel.Interceptors.IOperationInterceptor[]

私が見つけた唯一の奇妙な点は、このステップの直後にa が aMissingMethodExceptionとしてスローされる(ただしバブルアップしない) ことですが、そのスタック トレースが非常に短いため、何が問題なのかわかりません。FirstChanceException

2011-07-15T13:09:16.036 AppDomain.FirstChanceException
System.MissingMethodException: Member not found.
   at System.DefaultBinder.BindToMethod(BindingFlags bindingAttr, MethodBase[] match, Object[]& args, ParameterModifier[] modifiers, CultureInfo cultureInfo, String[] names, Object& state)

なぜ a がスローされているのか、イベントにMissingMethodExceptionサブスクライブしないとバブルしないのかはわかりませんが、正しく逆シリアル化されていない理由に関連している可能性があります。ただし、HTTP POST では正しくデシリアライズされるため、疑問があります。AppDomain.FirstChanceExceptionCustomerForm

アイデア?

4

2 に答える 2

1

int id問題は、URL がどのように解釈され、ハンドラーにマップされるかにあるようです。次のように、も受け取るハンドラー メソッドを追加すると、

CustomerResource Put(int id, CustomerForm customerForm)

できます。これは、次のリソース登録が原因である可能性があります。

ResourceSpace.Has.ResourcesOfType<CustomerResource>()
    .AtUri("/customers/{id}")

私はこれを持っていますが:

ResourceSpace.Has.ResourcesOfType<CustomerForm>()
    .WithoutUri

CustomerFormID を含めるように の登録を変更しようとしました。

ResourceSpace.Has.ResourcesOfType<CustomerForm>()
    .AtUri("/customers/{id}")

また、CustomerResourceCustomerForm登録の両方で ID をオプションにするには:

ResourceSpace.Has.ResourcesOfType<CustomerResource>()
    .AtUri("/customers/{*id}")

ResourceSpace.Has.ResourcesOfType<CustomerForm>()
    .AtUri("/customers/{*id}")

これはどれも役に立ちませんが、パラメーターをハンドラー メソッドに追加するint idと役に立ちます。これにより、OpenRasta が私のエンティティを正常に逆シリアル化できるので満足しています。

于 2011-10-21T07:19:10.853 に答える