[英]Null parameter with MVC Web-API in OWIN Self-Host
我将在本教程之后使用OWIN在Azure辅助角色上托管Web-API:
http://www.asp.net/web-api/overview/hosting-aspnet-web-api/use-owin-to-self-host-web-api http://www.asp.net/web-api /概述/托管-ASPNET的Web-API /主机ASPNET的Web-API在-AN-Azure的工人角色
请求正在路由。 断点在控制器方法内按预期停止,但使用[FromBody]属性修饰的方法参数始终为null。
贝娄是我的方法和课程的详细信息:
请求标题:
User-Agent: Fiddler
Content-Type: text/xml; charset=utf-8
Host: localhost:81
Content-Length: 365
请求机构:
<?xml version="1.0"?>
<Unit name="ShopActiVID" serialNumber="00123" macAddress="40:d8:55:aa:aa:aa" tzOffset="-0400" useDst="True">
<Door name="Shop Main" ID="146">
<count date="2014-06-19T16:58:31.0000000Z" in="0" out="0"/>
</Door>
<Door name="Conf. Area" ID="147">
<count date="2014-06-19T16:58:31.0000000Z" in="2" out="0"/>
</Door>
</Unit>
用作身体有效负载的类:
[DataContract(Name="Unit", IsReference=true)]
public class AddPeopleCountRequest
{
[DataMember(Name="name")]
public string Name { get; set; }
[DataMember(Name = "serialNumber")]
public string SerialNumber { get; set; }
[DataMember(Name = "macAddress")]
public string MacAddress { get; set; }
[DataMember(Name = "tzOffset")]
public string TzOffset { get; set; }
[DataMember(Name = "useDst")]
public bool UseDst { get; set; }
public List<Door> Doors { get; set; }
}
[DataContract(Name="Door", IsReference=true)]
public class Door
{
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "ID")]
public int Id { get; set; }
public List<Count> Counts { get; set; }
}
[DataContract(Name="count", IsReference=true)]
public class Count
{
[DataMember(Name = "date")]
public DateTime Time { get; set; }
[DataMember(Name = "in")]
public int In { get; set; }
[DataMember(Name = "out")]
public int Out { get; set; }
}
控制器方法:
[RoutePrefix("api/v1")]
public class CollectorController : ApiController
{
[HttpPost]
[Route("count")]
public async Task<IHttpActionResult> AddPeopleCountRecord([FromBody]AddPeopleCountRequest addCountRequest)
{
...
return Ok();
}
}
OWIN启动课程:
public class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
app.UseWebApi(config);
}
}
因此,每次我在fiddler上发布XML请求时,它都不会反序列化到控制器上的Action参数中。
那么我做错了什么?
谢谢! 真的很感激帮助!
问题在于使用数据(例如:name,serialNumber,macAddress)作为xml中的属性。 默认情况下,Web API的Xml格式化程序使用DataContractSerializer
作为序列化程序。 此序列化程序不支持将数据作为Xml中的属性。 您需要使用XmlSerializer
。 您可以更改默认格式化程序的设置以使用此序列化程序。
另外一般情况下,如果您没有看到要填充的操作参数,则可以检查ModelState
有效性以查找错误(如果有)。
if (!ModelState.IsValid)
{
return BadRequest(this.ModelState);
}
好吧终于搞定了。
首先进入Startup.cs,我已将序列化器更改为:
public class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
config.Formatters.XmlFormatter.UseXmlSerializer = true;
config.MapHttpAttributeRoutes();
app.UseWebApi(config);
}
}
然后,由于我们使用的是旧的XmlSerializar,因此我们无法将DataContract / Member属性保留在属性上。 我们应该使用XmlAttribute / XmlMember,如下面的代码所示,参数反序列化:
[XmlRoot("Unit")]
public class AddPeopleCountRequest
{
[XmlAttribute("name")]
public string Name { get; set; }
[XmlAttribute("serialNumber")]
public string SerialNumber { get; set; }
[XmlAttribute("macAddress")]
public string MacAddress { get; set; }
[XmlElement(ElementName="Door", Type=typeof(Door))]
public List<Door> Doors { get; set; }
}
public class Door
{
[XmlAttribute("name")]
public string Name { get; set; }
[XmlAttribute("ID")]
public int Id { get; set; }
[XmlElement(ElementName = "count", Type = typeof(Count))]
public List<Count> Counts { get; set; }
}
public class Count
{
[XmlAttribute("date")]
public DateTime Time { get; set; }
[XmlAttribute("in")]
public int In { get; set; }
[XmlAttribute("out")]
public int Out { get; set; }
}
谢谢大家的帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.