我有一个web api服务最初使用beta位,我已经重建使用发布版本位,我现在有这个问题。
我有一个POST操作,它将复杂选项作为唯一参数。当我以json格式发送带有正文的请求时,对象会按预期反序列化,但如果我发送XML,参数将为空。
在beta中,我通过禁用模型绑定来解决这个问题,如卡洛斯·菲格拉的博客文章在ASP.NETWeb API Beta上禁用模型绑定所述
但是,在RC中,他们删除了此方法正在实现的IRequest estContentReadPolicy。
我的行动:
public List<Models.Payload> Post([FromBody]Models.AimiRequest requestValues)
{
try
{
if (requestValues == null)
{
var errorResponse = new HttpResponseMessage();
errorResponse.StatusCode = HttpStatusCode.NotFound;
errorResponse.Content = new StringContent("parameter 'request' is null");
throw new HttpResponseException(errorResponse);
}
var metadataParams = new List<KeyValuePair<string, string>>();
foreach (Models.MetadataQueryParameter param in requestValues.Metadata)
{
metadataParams.Add(new KeyValuePair<string, string>(param.Name, param.Value));
}
List<Core.Data.Payload> data = _payloadService.FindPayloads(metadataParams, requestValues.ContentType, requestValues.RuleTypes);
var retVal = AutoMapper.Mapper.Map<List<Core.Data.Payload>, List<Models.Payload>>(data);
return retVal; // new HttpResponseMessage<List<Models.Payload>>(retVal);
}
catch (System.Exception ex)
{
_logger.RaiseError(ex);
throw;
}
}
我的模型:
public class AimiRequest
{
public MetadataQueryParameter[] Metadata { get; set; }
public string ContentType { get; set; }
public string RuleTypes { get; set; }
}
public class MetadataQueryParameter
{
public string Name { get; set; }
public string Value { get; set; }
}
我正在测试使用Fiddler向服务发送请求。
这工作并返回我预期的结果。
POST http://localhost:51657/api/search HTTP/1.1
User-Agent: Fiddler
Content-Type: application/json; charset=utf-8
Accept: application/json
Host: localhost:51657
Content-Length: 219
{
"ContentType":null,
"RuleTypes":null,
"Metadata":[
{
"Name":"ClientName",
"Value":"Client One"
},
{
"Name":"ClientName",
"Value":"Client Two"
}
]
}
这会失败,因为request estValue参数为null
POST http://localhost:51657/api/search HTTP/1.1
User-Agent: Fiddler
Content-Type: application/xml; charset=utf-8
Accept: application/xml
Host: localhost:51657
Content-Length: 213
<AimiRequest>
<ContentType />
<RuleTypes />
<Metadata>
<MetadataQueryParameter>
<Name>ClientName</Name>
<Value>Client One</Value>
</MetadataQueryParameter>
<MetadataQueryParameter>
<Name>ClientName</Name>
<Value>Client Two</Value>
</MetadataQueryParameter>
</Metadata>
</AimiRequest>
通过向Global. asax.cs中的ApplicationStart()方法添加以下行,您的原始XML请求应该可以工作:
var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
xml.UseXmlSerializer = true;
缺省情况下,WebAPI使用DataDiamtSerializer类,该类需要XML请求中的额外信息。
XmlSerializer对我来说似乎工作得更顺利,因为我不必将模型的名称添加到每个XML请求中。
我再次在Mike Wasson的文章中找到了我的信息:http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#xml_media_type_formatter
我遇到了和你一样的问题,并通过使用XmlMediaTypeFor物质序列化对象找到了解决方案,如下所述:http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#testing_object_serialization.我使用了文章底部“测试对象序列化”部分中的代码,并用我的模型替换了他的Person对象。
当我序列化我的对象时,我注意到根节点添加了以下属性:
xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.datacontract.org/2004/07/NAMESPACE.OF.YOUR.MODEL"
如果您像这样将这些属性添加到您的xml中,您的控制器应该正确序列化request estValue对象:
<AimiRequest xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.datacontract.org/2004/07/NAMESPACE.OF.YOUR.MODEL">
<ContentType />
<RuleTypes />
<Metadata>
<MetadataQueryParameter>
<Name>ClientName</Name>
<Value>Client One</Value>
</MetadataQueryParameter>
<MetadataQueryParameter>
<Name>ClientName</Name>
<Value>Client Two</Value>
</MetadataQueryParameter>
</Metadata>
</AimiRequest>