接受列表参数的 odata 操作始终为 null

odata action accepting list parameter is always null

我的 odata 控制器有问题。

我想发送一个地址对象列表,但收到的参数总是空的。

我的终点是这样的:

    [EnableQuery]
    public IHttpActionResult SetCoordinatesOnAddressList(IEnumerable<Address> addresses)
    {
        var result = addresses.Select(address => _coordinates.GetAddressCoordinates(address)).ToList();
        return Ok(result);
    } 

我在 WebApiConfig 中设置了这个

builder.EntityType<Address>().Collection
            .Action("SetCoordinatesOnAddressList")
            .ReturnsFromEntitySet<Address>("Addresses");

我正在使用 Postman 发送请求。

我的请求作为 post 请求发送,如下所示:

[{"StreetName":"Some street","StreetNumber":"8","ZipCode":1234,"Town":"Some town"}]

我有一个不同的端点,它采用单个地址而不是 IEnumerable,并且与相同的 json-请求(没有 [])一起工作,因此 [=45= 中的字段] 是正确的。

总结一下: 我的 IEnumerable 端点总是收到 null。 知道是什么原因造成的吗?

谢谢。

编辑:

我尝试更改我的端点以接受 AddressDTO,如下所示:

public IHttpActionResult SetCoordinatesOnAddressList(AddressDTO addresses)
{
    return Ok(2);
}

这是一个 AddressDTO:

public class AddressDTO
{
    public IEnumerable<Address> Addresses { get; set; }
}

如果我尝试 post 这个:

{"Addresses": [{"StreetName":"Some street","StreetNumber":"8","ZipCode":1234,"Town":"Some town"}]}

我收到这个错误:

{
  "error": {
    "code": "",
    "message": "The request entity's media type 'application/json' is not supported for this resource.",
    "innererror": {
      "message": "No MediaTypeFormatter is available to read an object of type 'AddressDTO' from content with media type 'application/json'.",
      "type": "System.Net.Http.UnsupportedMediaTypeException",
      "stacktrace": "   at System.Net.Http.HttpContentExtensions.ReadAsAsync[T](HttpContent content, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)\\r\\n   at System.Net.Http.HttpContentExtensions.ReadAsAsync(HttpContent content, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)\\r\\n   at System.Web.Http.ModelBinding.FormatterParameterBinding.ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)"
    }
  }
}

如果像这样将集合作为对象上的 属性 命名地址发送会怎样?

{"addresses": [{"StreetName":"Some street","StreetNumber":"8","ZipCode":1234,"Town":"Some town"}]}

对于action,为什么不在控制器中使用ODataActionParameter作为方法的参数呢?

这里有一个关于如何使用 Action 的简单教程:

http://odata.github.io/WebApi/#04-07-action-parameter-support

其中,“Entity and Collection of Entity parameter”部分是相同的场景,因为我看到你定义了"Address"作为实体类型。

builder.EntityType()....

但是,“Complex and Collection of Complex parameter”是复杂类型的场景。

我无法使用 Odata 控制器让它工作,我不得不克服它,所以我最终做的是创建一个工作正常的常规 API 控制器。

public IHttpActionResult SetCoordinatesOnAddressList(IEnumerable<Address> addresses)
{
    //Do stuff
}

无需任何设置即可接受 Address IEnumerable,并且正常工作。

[HttpPost]
[ODataRoute("SetCoordinatesOnAddressList")]
public IHttpActionResult SetCoordinatesOnAddressList(ODataActionParameters parameters)
{
    IEnumerable<Address> addresses =  parameters["addresses"] as IEnumerable<Address>;
    var result = addresses.Select(address => _coordinates.GetAddressCoordinates(address)).ToList();
    return Ok(result);
} 

WebAPIConfig 应如下所示

builder.Action("SetCoordinatesOnAddressList").Returns<IHttpActionResult>().CollectionParameter<Address>("addresses");

它没有绑定到实体,因此可以这样访问 localhost/odata/SetCoordinatesOnAddressList