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; }
}

我的问题是当CustomerFormPUT 到服务器时,OpenRasta 无法正确反序列化它。尽管它是从客户端成功发送的,但它的作用是用一ContactInfo组反序列化它。null我什至深入研究IRequest.Entity.Stream以确保我需要的 XML 确实存在,它是:

<?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包含必要的数据?我有确保序列化和反序列化完美工作的测试,我什至有一个完全相同的处理程序也可以工作。只是当 HTTP 方法为 PUT 时,它已设置为.CustomerFormPut(CustomerForm)Post(CustomerForm)CustomerFormContactInfonull

我已经彻底阅读了 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[]

我发现的唯一奇怪之处是在这一步之后 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)

我不知道为什么 aMissingMethodException被抛出以及为什么如果我不订阅该AppDomain.FirstChanceException事件它不会冒泡,但这可能与为什么 myCustomerForm没有正确反序列化有关。但是,由于它确实在 HTTP POST 上正确反序列化,我对此表示怀疑。

想法?

4

2 回答 2

1

听起来很古怪,但您是否尝试过将 id 移动到 CustomerForm 对象的顶部?

[XmlRoot("customer", Namespace = ClientSettings.Namespace)]
public class CustomerForm : FormBase, ICustomer
{
    [XmlAttribute("id")]
    public int Id { get; set; }

    [XmlElement("contact-info")]
    public ContactInfo ContactInfo { get; set; }
}

Openrasta 使用(糟糕的).net 数据合约 xml 序列化程序,它对元素位置很敏感。实际上,我们编写了自己的序列化程序,它只是简单地恢复为传统的“点网”xml 序列化程序。

于 2011-07-15T14:08:57.800 回答
1

问题似乎在于如何解释 URL 并将其映射到处理程序,因为如果我添加一个也采用 的处理程序方法int id,如下所示:

CustomerResource Put(int id, CustomerForm customerForm)

有用。这可能是由于以下资源注册:

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

虽然我有这个:

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

我试图修改注册CustomerForm以包含一个 ID:

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

并且还要使 ID 在CustomerResourceCustomerForm注册上都是可选的:

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

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

这些都没有帮助,但是将int id参数添加到处理程序方法中,所以我很高兴,因为这使得 OpenRasta 成功反序列化我的实体。

于 2011-10-21T07:19:10.853 回答