如何在asp.net WebAPI POST路由的Post正文中格式化XML

时间:2019-04-26 01:26:00

标签: asp.net rest asp.net-web-api asp.net-web-api2

我有一个asp.net WebAPI RESTful服务,其中有一个用于GPS位置的POST端点。

服务器控制器具有以下路由。

public HttpResponseMessage PostGpsPositions(GpsPositionsModel positions)

身体类别如下

 public class GpsPositionsModel 
  {
    [Required]
    public int SenderId { get; set; }

    [Required]
    public List<GPSData> Positions { get; set; } 
 }

  public class GPSData 
  {       
    [Required]
    public double X { get; set; }

    [Required]
    public double Y { get; set; }

    [Required]
    public double Z { get; set; }    
  }

我总是只使用json,但是有人问我是否可以在XML中提交尸体。

通过添加Content-Type:"application/xml"标头,似乎应该可以实现。

我本以为格式如下所示。

    <?xml version="1.0"?>
    <GpsPositionsModel>
      <SenderId>1</SenderId>
      <Positions>
        <GPSData>
            <x>1.1</x>
            <y>1.1</y>
            <z>1.1</z>
        </GPSData>    
      </Positions>
    </GpsPositionsModel>

但这只是行不通,我找回400 Bad Request

我在服务器上有一个验证筛选器...

ValidationFilterAttribute : ActionFilterAttribute

OnActionExecuting中,我看到它确实具有XML内容标头,但模型状态为false ...

enter image description here

所以,我的问题是XML应该在这里格式化吗?我是否需要在结构中的某个地方ArrayOf,如果需要,该如何将其应用于要发送的列表?

在此先感谢您的帮助

[UPDATE 19 Apr 19]

添加了注释中建议的属性。

所以我在服务器端。

    namespace Models.Common
    {
      [DataContract(Namespace = "http://mynamespace.com")]
      public class GpsPositionsModel
      {
        [DataMember]
        [Required]
        public int SenderId { get; set; }

        [DataMember]
        [Required]
        public List<GPSData> Positions { get; set; }
      }

      [DataContract(Namespace = "http://mynamespace.com")]
      public class GPSData
      {
        [DataMember]
        [Required]
        public double X { get; set; }

        [DataMember]
        [Required]
        public double Y { get; set; }

        [DataMember]
        [Required]
        public double Z { get; set; }
      }
    }

控制器

    [HttpPost]
    [Route("gps")]
    public HttpResponseMessage SubmitGpsData([FromBody]GpsPositionsModel gpsData)
    {      
      return new HttpResponseMessage();
    }

使用邮递员,我使用...打电话给

    <?xml version="1.0"?>
    <GpsPositionsModel xmlns="http://schemas.datacontract.org/2004/07/http://mynamespace.com">
      <SenderId>1</SenderId>
      <Positions>
           <GPSData xmlns="http://schemas.datacontract.org/2004/07/http://mynamespace.com">
                        <x>1.1</x>
                        <y>1.1</y>
                        <z>1.1</z>                          
           </GPSData>
        <GPSData xmlns="http://schemas.datacontract.org/2004/07/http://mynamespace.com">
                        <x>1.1</x>
                        <y>1.1</y>
                        <z>1.1</z>                          
           </GPSData>
      </Positions>
    </GpsPositionsModel>

在Postman控制台中,我得到了。

enter image description here

我正在使用WebAPI2,asp.net完整框架

    <package id="Microsoft.AspNet.Cors" version="5.2.4" targetFramework="net47" />
      <package id="Microsoft.AspNet.WebApi" version="5.2.4" targetFramework="net47" />
      <package id="Microsoft.AspNet.WebApi.Client" version="5.2.4" targetFramework="net47" />
      <package id="Microsoft.AspNet.WebApi.Core" version="5.2.4" targetFramework="net47" />
      <package id="Microsoft.AspNet.WebApi.Cors" version="5.2.4" targetFramework="net47" />
      <package id="Microsoft.AspNet.WebApi.Owin" version="5.2.4" targetFramework="net47" />
      <package id="Microsoft.AspNet.WebApi.Tracing" version="5.2.4" targetFramework="net47" />
      <package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.4" targetFramework="net47" />

2 个答案:

答案 0 :(得分:0)

要发布xml,您需要以以下格式指定xmlns: http://schemas.datacontract.org/2004/07/Clr.Namespace

因此,在您的情况下,您需要像这样发布xml:

<GpsPositionsModel xmlns="http://schemas.datacontract.org/2004/07/{namespance containing GpsPositionsModel class}">
    <Positions>
        <GPSData>
            <X>1</X>
            <Y>1</Y>
            <Z>2</Z>
        </GPSData>
    </Positions>
    <SenderId>1</SenderId>
    </GpsPositionsModel>

如果GpsPositionsModel类不在任何命名空间之内,则可以将其留空,例如: xmlns="http://schemas.datacontract.org/2004/07/

参考:https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/data-contract-names

答案 1 :(得分:0)

尝试在操作方法的参数中添加[FromBody]属性

public HttpResponseMessage PostGpsPositions([FromBody]GpsPositionsModel positions)

此外,对于模型

在类名上添加[DataContract],在模型中的每个属性上添加[DataMember]