2

我正在尝试使用 OData 将数据发送到 Web API。但是接收到的实体总是空的。

我有这个使用 JQuery 的电话:

        $.ajax({
            url: "/odata/Products",
            type: "POST",
            //contentType: "application/json;odata=verbose",
            contentType: 'application/json; charset=utf-8',
            data: JSON.stringify(productToAdd),
            dataType: "json",
            success: function () {
                alert("Server call has been OK!!");
            },
            error: function () {
                alert("Server call has been failed!!");
            }
        });

productToAdd 对象如下:

{"name":"Apple","description":"Good!!","price":"12.3","category":"Fruit"}

我的控制器是:

public class ProductsController : EntitySetController<Product, string>
{
    private IProductService _prodSvc;

    public ProductsController(IProductService prodSvc)
    {
        _prodSvc = prodSvc;
    }

    [Queryable]
    public override IQueryable<Product> Get()
    {
        return _prodSvc.GetAllProducts();
    }

    protected override Product CreateEntity(Product product)
    {
       var addedProduct = _prodSvc.AddProduct(product);
       return addedProduct;
    }
}

我也尝试使用 datajs-1.10.js 框架,但我得到了相同的结果。

        OData.request(
          {
              requestUri: "/odata/Products",
              method: "POST",
              data: productToAdd
          },
          function (data) {
              alert("Server call has been OK!!");
          }
        );

我认为反序列化 JSON 对象时出了点问题,但我不知道是什么。你可以帮帮我吗?

谢谢!!

4

1 回答 1

1

由于某种原因,看起来 web api 的模型绑定器的行为方式与我们对 mvc 中的模型绑定所期望的方式不同,但是这里的上下文略有不同,表单发布与 JSON 不太一样对象有效载荷...

例如:如果我在 C# 中定义以下类...

class Foo 
{
    public int Id { get; set; }
    public string Bar { get; set; }
}

...然后给出...的方法签名

public void SomeMethod(Foo data) { ... }

...在 MVC 中,我可以发布任何任意的数据块,并且至少与某些属性匹配的任何内容都会被绑定。Web API 会发生这种情况,但前提是您发布了“application/x-www-form-urlencoded”的内容类型并且我对我的数据进行了字符串化。

但是,如果您想发布正确的 JSON,则必须明确且正确,并且如果您少提供 1 个属性或额外的属性,它将失败并出现一个非常模糊的模型状态验证错误,并且只会说“发布的数据验证失败”之类的内容,没有帮助。

您应该能够通过在控制器的第一行放置一个断点然后在 Modelstate 中检查该值来看到这一点。没有例外,只是验证失败并且参数为空。

然而,数据应该仍然存在,并且没有什么能阻止您使用 2 或 3 行代码自己从请求流中手动解析它。在这种情况下,我将建议您确认您的 json 与您的 DTO 完全匹配。

鉴于是这种情况,那么这应该可以工作...

$.ajax({
    type: method,
    url: url,
    data: someObject,
    dataType: 'json',
    beforeSend: function (xhr) {
        xhr.setRequestHeader("Content-Type", "application/json;odata=minimalmetadata");
        xhr.setRequestHeader("Accept", "application/json;odata=minimalmetadata");
        xhr.setRequestHeader("Accept-Charset", "UTF-8");
        // add say auth headers here for secure endpoints
    },
    success: function (newObj) {
        // job done
    },
    error: function (e) {
        // nope, examine what server said
    }
});
于 2015-08-26T08:26:29.620 回答