【问题标题】:POST to Web API OData, the entity that is received is nullPOST 到 Web API OData,收到的实体为空
【发布时间】:2013-04-19 17:42:49
【问题描述】:

我正在尝试使用 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 对象时出了点问题,但我不知道是什么。你能帮帮我吗?

谢谢!!

【问题讨论】:

  • 一般来说,我建议您在遇到此类问题时首先尝试确定问题是客户端问题还是服务器端问题。使用Fiddler 之类的工具(或任何其他可以监控您的 HTTP 请求和响应的工具)查看从服务器返回的内容。服务器是返回成功的状态码还是错误?
  • 你能检查你控制器上的 ModelState 属性吗?那应该有关于反序列化失败的任何信息。

标签: jquery post asp.net-web-api odata


【解决方案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
    }
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-14
    • 2014-06-19
    • 2018-01-24
    • 1970-01-01
    • 1970-01-01
    • 2012-11-07
    • 1970-01-01
    相关资源
    最近更新 更多