发送XML当ASPNET的WebAPI POST参数为null [英] AspNet WebApi POST parameter is null when sending XML

查看:1123
本文介绍了发送XML当ASPNET的WebAPI POST参数为null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用原来我已经使用了发布候选位重建公测位的网络API服务,现在我有这个问题。

我有一个POST操作,需要一个复杂的选项作为唯一的参数。当我送与JSON格式的身体要求如期对象deserialised,但如果我发送XML而不是参数为null。

在我工作围绕这通过禁用模型作为卡洛斯·费圭的博客文章<一个描述结合的测试href=\"http://blogs.msdn.com/b/carlosfigueira/archive/2012/02/27/disabling-model-binding-on-asp-net-web-apis-beta.aspx\">Disabling

上的ASP.NET Web API的测试模型绑定

在RC但他们已经删除了IRequestContentReadPolicy,这种方法正在实施。

我的行动:

 公开名单&LT; Models.Payload&GT;帖子([FromBody] Models.AimiRequest requestValues​​)
{
  尝试
  {
    如果(requestValues​​ == NULL)
    {
      VAR errorResponse =新的Htt presponseMessage();
      errorResponse.Status code =的HTTPStatus code.NotFound;
      errorResponse.Content =新的StringContent(参数请求为空);
      抛出新的Htt presponseException(errorResponse);
    }
    VAR metadataParams =新的List&LT; KeyValuePair&LT;字符串,字符串&GT;&GT;();
    的foreach(在requestValues​​.Metadata Models.MetadataQueryParameter参数)
    {
      metadataParams.Add(新KeyValuePair&LT;字符串,字符串&GT;(param.Name,param.Value));
    }
    清单&LT; Core.Data.Payload&GT;数据= _payloadService.FindPayloads(metadataParams,requestValues​​.ContentType,requestValues​​.RuleTypes);
    VAR retVal的= AutoMapper.Mapper.Map&LT;名单,LT; Core.Data.Payload&gt;中列出&LT; Models.Payload&GT;&GT;(数据);
    返回retVal的; //新的Htt presponseMessage&LT;名单,LT; Models.Payload&GT;&GT;(retVal的);
  }
  赶上(System.Exception的前)
  {
    _logger.RaiseError(除息);
    扔;
  }
}

我的模型:

 公共类AimiRequest
{
  公共MetadataQueryParameter [] {元数据获取;组; }
  公共字符串的ContentType {搞定;组; }
  公共字符串RuleTypes {搞定;组; }
}公共类MetadataQueryParameter
{
  公共字符串名称{;组; }
  公共字符串值{获得;组; }
}

我使用招发送请求到服务测试。

这工作,并返回我期望的结果。

  POST HTTP://本地主机:51657 / API /搜索HTTP / 1.1
用户代理:提琴手
内容类型:应用程序/ JSON的;字符集= UTF-8
接受:应用/ JSON
主机:本地主机:51657
内容长度:219{
  的ContentType:空,
  RuleTypes:空,
  元数据:
    {
    名称:CLIENTNAME
    值:客户一
    },
    {
    名称:CLIENTNAME
    值:两个客户端
    }
  ]
}

这将会失败,因为requestValues​​参数为空

  POST HTTP://本地主机:51657 / API /搜索HTTP / 1.1
用户代理:提琴手
内容类型:应用程序/ xml的;字符集= UTF-8
接受:应用/ XML
主机:本地主机:51657
内容长度:213&LT; AimiRequest&GT;
  &LT;的ContentType /&GT;
  &LT; RuleTypes /&GT;
  &LT;&元数据GT;
    &LT; MetadataQueryParameter&GT;
      &LT;名称&gt;&CLIENTNAME LT; /名称&gt;
      &LT; VALUE&GT;客户端的One&LT; /价值与GT;
    &LT; / MetadataQueryParameter&GT;
    &LT; MetadataQueryParameter&GT;
      &LT;名称&gt;&CLIENTNAME LT; /名称&gt;
      &LT; VALUE&GT;客户2路和LT; /价值与GT;
    &LT; / MetadataQueryParameter&GT;
  &LT; / - 元数据GT;
&LT; / AimiRequest&GT;


解决方案

通过添加以下行的ApplicationStart()方法,您的
Global.asax.cs中,原始的XML请求应该工作:

  VAR XML = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
xml.UseXmlSerializer = TRUE;

在默认情况下,在Web API使用的DataContractSerializer类,它需要在XML请求的额外信息。

XmlSerializer的,似乎更适合我的工作顺利,因为我没有到模型的namepsace添加到每个XML请求。

再一次,我发现我的迈克·沃森的文章:<一href=\"http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#xml_media_type_formatter\">http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#xml_media_type_formatter

I have a web api service originally using beta bits which I've rebuilt using the release candidate bits and I'm now having this problem.

I have a POST action that takes a complex option as the only parameter. When I send the request with the body in json format the object is deserialised as expected, but if I send XML instead the parameter is null.

In the beta I worked around this by disabling model binding as described in Carlos Figueira's blog post Disabling model binding on ASP.NET Web APIs Beta

In the RC however they have removed the IRequestContentReadPolicy that this method was implementing.

My action:

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

My model:

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

I'm testing using Fiddler to send requests to the service.

This works and returns me the expected results.

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"
    }
  ]
}

This fails because the requestValues parameter is 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>

解决方案

By adding the following lines to the ApplicationStart() method in your Global.asax.cs, your original XML request should work:

var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
xml.UseXmlSerializer = true;

By default, the Web API uses the DataContractSerializer class, which requires extra information in the XML request.

The XmlSerializer seems to work more smoothly for me, since I don't have to add the model's namepsace to each XML request.

Once again, i found my information in Mike Wasson's article: http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#xml_media_type_formatter

这篇关于发送XML当ASPNET的WebAPI POST参数为null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆