[英]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.