如何使用 IRequiresRequestStream POST 一个 xml 文件到 ServiceStack
How to POST an xml file to ServiceStack with IRequiresRequestStream
阅读了一些关于这个主题的不同 SO Posts and the Docs 后,我仍然感到困惑,无法通过我的服务端点上的 RequestBindingException。例如,我想 POST 以下 xml 到服务 POSTMAN.
<LeadApplications>
<LeadApplication>
<Email>daffy.duck@example.com</Email>
<FirstName>Joey</FirstName>
<MiddleName>Disney</MiddleName>
<LastName>Duck</LastName>
<Street1>1 Disneyland Street</Street1>
<Street2>2 Disneyland Street</Street2>
<City>PAUMA VALLEY</City>
<State>CA</State>
<Zip>92503</Zip>
</LeadApplication>
</LeadInformations>
[Restrict(RequestAttributes.Xml)]
public class LeadData : IRequiresRequestStream
{
public Stream RequestStream { get; set; }
}
public object Post(ServiceModel.Types.DirectApi.Legacy.LeadData request)
{
return null;
}
Routes.Add<ServiceModel.Types.DirectApi.Legacy.LeadData>("/Leads/LeadData/", "POST", "LMS - DirectApi")
我曾希望这是解决 .NET 反序列化 属性 排序问题的最佳方法。
原始请求/响应
POST http://localhost/LO.Leads.Receiver/api/Leads/LeadData/ HTTP/1.1
Host: localhost
Connection: keep-alive
Content-Length: 381
Origin: chrome-extension://aejoelaoggembcahagimdiliamlcdmfm
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2289.0 Safari/537.36
Content-Type: application/xml
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: ss-pid=fhjNz7BGBBqgps6zsnUo; ss-opt=perm; X-UAId=f94092eb-fae8-4b39-b5ff-ae3b404645d8; m=34e2:|41b8:f|4a01:t|ca3:t|b12:f|47ba:t|77cb:t
<LeadApplications>
<LeadApplication>
<Email>daffy.duck@example.com</Email>
<FirstName>Joey</FirstName>
<MiddleName>Disney</MiddleName>
<LastName>Duck</LastName>
<Street1>1 Disneyland Street</Street1>
<Street2>2 Disneyland Street</Street2>
<City>PAUMA VALLEY</City>
<State>CA</State>
<Zip>92503</Zip>
</LeadApplication>
</LeadApplications>
HTTP/1.1 400 Bad Request
Cache-Control: private
Content-Type: application/xml
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
X-MiniProfiler-Ids: ["6f4255ee84fa45d1a2e05de8a268fc37","a52523648aed4dfaae96e607d07b5163","f9cf295e8e7b4aa1b0579929e61d59a5","7b4daa97fc8d427cb952b17414c4da31","707e7624fa4546c3911a9cb3ce5e6a36"]
X-Powered-By: ASP.NET
Date: Wed, 28 Jan 2015 02:19:30 GMT
Content-Length: 538
<?xml version="1.0" encoding="utf-8"?><ErrorResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.servicestack.net/types"><ResponseStatus><ErrorCode>RequestBindingException</ErrorCode><Message>Unable to bind request</Message><StackTrace> at ServiceStack.Host.RestHandler.CreateRequest(IRequest httpReq, IRestPath restPath)
at ServiceStack.Host.RestHandler.ProcessRequestAsync(IRequest httpReq, IResponse httpRes, String operationName)</StackTrace><Errors i:nil="true" /></ResponseStatus></ErrorResponse>
谢谢,
斯蒂芬
存在一个问题,因为请求内容类型与现有的已注册序列化程序(即 XML)匹配,它仍会尝试使用该序列化程序反序列化正文。现在修复了忽略 IRequiresRequestStream
请求 from this commit.
的所有序列化程序
这让您现在可以创建访问流并将其读取为正常 XML:
[Restrict(RequestAttributes.Xml)]
[Route("/Leads/LeadData/", "POST", Notes = "LMS - DirectApi")]
public class CustomXml : IRequiresRequestStream
{
public Stream RequestStream { get; set; }
}
public class RawRequestService : IService
{
public object Any(CustomXml request)
{
var xml = request.RequestStream.ReadFully().FromUtf8Bytes();
return xml;
}
}
您可以使用 HTTP Utils 调用,例如:
var xml = @"<LeadApplications>
<LeadApplication>
<Email>daffy.duck@example.com</Email>
<FirstName>Joey</FirstName>
<MiddleName>Disney</MiddleName>
<LastName>Duck</LastName>
<Street1>1 Disneyland Street</Street1>
<Street2>2 Disneyland Street</Street2>
<City>PAUMA VALLEY</City>
<State>CA</State>
<Zip>92503</Zip>
</LeadApplication>
</LeadApplications>";
var requestUrl = Config.ServiceStackBaseUri + "/Leads/LeadData/";
var responseXml = requestUrl.PostXmlToUrl(xml);
Assert.That(responseXml, Is.EqualTo(xml));
此更改适用于 v4.0.37+,现在是 available on MyGet。如果您将请求更改为使用不同的 Content-Type,例如application/xml-lead
与任何现有的序列化程序都不匹配,但是您需要删除 [Restrict]
,它只允许 XML 请求。
阅读了一些关于这个主题的不同 SO Posts and the Docs 后,我仍然感到困惑,无法通过我的服务端点上的 RequestBindingException。例如,我想 POST 以下 xml 到服务 POSTMAN.
<LeadApplications>
<LeadApplication>
<Email>daffy.duck@example.com</Email>
<FirstName>Joey</FirstName>
<MiddleName>Disney</MiddleName>
<LastName>Duck</LastName>
<Street1>1 Disneyland Street</Street1>
<Street2>2 Disneyland Street</Street2>
<City>PAUMA VALLEY</City>
<State>CA</State>
<Zip>92503</Zip>
</LeadApplication>
</LeadInformations>
[Restrict(RequestAttributes.Xml)]
public class LeadData : IRequiresRequestStream
{
public Stream RequestStream { get; set; }
}
public object Post(ServiceModel.Types.DirectApi.Legacy.LeadData request)
{
return null;
}
Routes.Add<ServiceModel.Types.DirectApi.Legacy.LeadData>("/Leads/LeadData/", "POST", "LMS - DirectApi")
我曾希望这是解决 .NET 反序列化 属性 排序问题的最佳方法。
原始请求/响应
POST http://localhost/LO.Leads.Receiver/api/Leads/LeadData/ HTTP/1.1
Host: localhost
Connection: keep-alive
Content-Length: 381
Origin: chrome-extension://aejoelaoggembcahagimdiliamlcdmfm
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2289.0 Safari/537.36
Content-Type: application/xml
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: ss-pid=fhjNz7BGBBqgps6zsnUo; ss-opt=perm; X-UAId=f94092eb-fae8-4b39-b5ff-ae3b404645d8; m=34e2:|41b8:f|4a01:t|ca3:t|b12:f|47ba:t|77cb:t
<LeadApplications>
<LeadApplication>
<Email>daffy.duck@example.com</Email>
<FirstName>Joey</FirstName>
<MiddleName>Disney</MiddleName>
<LastName>Duck</LastName>
<Street1>1 Disneyland Street</Street1>
<Street2>2 Disneyland Street</Street2>
<City>PAUMA VALLEY</City>
<State>CA</State>
<Zip>92503</Zip>
</LeadApplication>
</LeadApplications>
HTTP/1.1 400 Bad Request
Cache-Control: private
Content-Type: application/xml
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
X-MiniProfiler-Ids: ["6f4255ee84fa45d1a2e05de8a268fc37","a52523648aed4dfaae96e607d07b5163","f9cf295e8e7b4aa1b0579929e61d59a5","7b4daa97fc8d427cb952b17414c4da31","707e7624fa4546c3911a9cb3ce5e6a36"]
X-Powered-By: ASP.NET
Date: Wed, 28 Jan 2015 02:19:30 GMT
Content-Length: 538
<?xml version="1.0" encoding="utf-8"?><ErrorResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.servicestack.net/types"><ResponseStatus><ErrorCode>RequestBindingException</ErrorCode><Message>Unable to bind request</Message><StackTrace> at ServiceStack.Host.RestHandler.CreateRequest(IRequest httpReq, IRestPath restPath)
at ServiceStack.Host.RestHandler.ProcessRequestAsync(IRequest httpReq, IResponse httpRes, String operationName)</StackTrace><Errors i:nil="true" /></ResponseStatus></ErrorResponse>
谢谢, 斯蒂芬
存在一个问题,因为请求内容类型与现有的已注册序列化程序(即 XML)匹配,它仍会尝试使用该序列化程序反序列化正文。现在修复了忽略 IRequiresRequestStream
请求 from this commit.
这让您现在可以创建访问流并将其读取为正常 XML:
[Restrict(RequestAttributes.Xml)]
[Route("/Leads/LeadData/", "POST", Notes = "LMS - DirectApi")]
public class CustomXml : IRequiresRequestStream
{
public Stream RequestStream { get; set; }
}
public class RawRequestService : IService
{
public object Any(CustomXml request)
{
var xml = request.RequestStream.ReadFully().FromUtf8Bytes();
return xml;
}
}
您可以使用 HTTP Utils 调用,例如:
var xml = @"<LeadApplications>
<LeadApplication>
<Email>daffy.duck@example.com</Email>
<FirstName>Joey</FirstName>
<MiddleName>Disney</MiddleName>
<LastName>Duck</LastName>
<Street1>1 Disneyland Street</Street1>
<Street2>2 Disneyland Street</Street2>
<City>PAUMA VALLEY</City>
<State>CA</State>
<Zip>92503</Zip>
</LeadApplication>
</LeadApplications>";
var requestUrl = Config.ServiceStackBaseUri + "/Leads/LeadData/";
var responseXml = requestUrl.PostXmlToUrl(xml);
Assert.That(responseXml, Is.EqualTo(xml));
此更改适用于 v4.0.37+,现在是 available on MyGet。如果您将请求更改为使用不同的 Content-Type,例如application/xml-lead
与任何现有的序列化程序都不匹配,但是您需要删除 [Restrict]
,它只允许 XML 请求。