Http OpenRasta can';无法在PUT时正确反序列化实体

Http OpenRasta can';无法在PUT时正确反序列化实体,http,deserialization,put,openrasta,Http,Deserialization,Put,Openrasta,在处理放在OpenRasta处理程序中的HTTP时,我遇到了一些非常奇怪的行为。处理程序方法签名如下所示: public CustomerResource Put(CustomerForm customerForm) [XmlRoot("customer", Namespace = ClientSettings.Namespace)] public class CustomerForm : FormBase, ICustomer { [XmlElement("contact-info"

在处理放在OpenRasta处理程序中的HTTP时,我遇到了一些非常奇怪的行为。处理程序方法签名如下所示:

public CustomerResource Put(CustomerForm 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; }
}
[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; }
}
CustomerResource Put(int id, 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");
ContactInfo
如下所示:

public CustomerResource Put(CustomerForm 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; }
}
[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; }
}
CustomerResource Put(int id, CustomerForm customerForm)
我的问题是当
CustomerForm
被放入服务器时,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>
我发现的唯一奇怪之处是,在这一步之后,
MissingMethodException
作为
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)
我不知道为什么会抛出
MissingMethodException
,如果我不订阅
AppDomain.FirstChanceException
事件,为什么它不会冒泡,但这可能与我的
CustomPerform
未正确反序列化有关。然而,由于它在HTTP POST上确实正确地反序列化了,我对此表示怀疑


想法?

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

[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序列化程序。实际上,我们编写了自己的serialiser,它简单地恢复为传统的“dot-net”xml序列化程序。

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

public CustomerResource Put(CustomerForm 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; }
}
[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; }
}
CustomerResource Put(int id, CustomerForm customerForm)
它起作用了。这可能是由于以下资源注册造成的:

ResourceSpace.Has.ResourcesOfType<CustomerResource>()
    .AtUri("/customers/{id}")
还可以在
CustomerResource
CustomerPerform
注册中选择ID:

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

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

所有这些都没有帮助,但是将
int id
参数添加到handler方法中确实有帮助,因此我很高兴这能使OpenRasta成功地反序列化我的实体。

感谢您的建议,但是您可以从我的
ResourceSpace
配置中看到,我使用的不是
DataContractSerializer
,而是老式的
XmlSerializer
AsXmlSerializer().ForMediaType(“application/xml;q=0.2”)
。不过,我不明白为什么元素的位置很重要。正如我所写的,OpenRasta在一篇文章中进行了完美的反序列化。你能手动反序列化你粘贴在这里的内容吗?这两种方式都不重要,但你永远不知道,是的,对象序列化和反序列化都很好。我甚至可以从
IRequest.Entity.Stream
手动反序列化对象,但OpenRasta并没有为我自动进行反序列化。这确实是一个奇怪的问题。活页夹内部的MissingMethodException很可能是问题的一部分。问题是,在我看来,编解码器的工作方式并不是问题的根源。然而,我可能会想,因为您跨两种资源重用了处理程序(您应该避免,因为选择正确的操作会变得有点混乱),编解码器可能最终尝试反序列化错误的类型(id是否有可能没有填充?)。你能在邮件列表上发送一个复制项目以便我进一步调查吗?啊啊。好吧,这很有道理。您可以看到,模型可以从键/值对(可以来自URI参数或支持读取键/值对的编解码器,如html表单)构建,也可以由只支持构建完整对象的编解码器构建(datacontract序列化程序可以这样做)。在这个阶段,您不能混搭(也许这是我们应该添加的),因此将Id添加到CustomerResource将不起作用。出于安全考虑,我也不想让它工作。也就是说,{*id}不是我们支持的语法,所以我很惊讶它没有对您产生影响:)