【问题标题】:Web API parameter binding not workingWeb API 参数绑定不起作用
【发布时间】:2014-12-29 14:55:53
【问题描述】:

我有两个实体类DonorUser。 Donor 是 User 的子类,如下所示

public abstract class User {
    [Key]
    public long Id { get; set; }
    ...
}    

public class Donor : User {
    public string AlternateMobileNumber { get; set; }
    ...
}

如下所示的 Web api 控制器操作接收 POST 请求,正文中包含 JSON 数据

public class DonorsController : ApiController  {

    //POST: api/Donors/EditDonor
    [HttpPost]
    public HttpResponseMessage EditDonor([FromBody] Donor donor) {
        ...
    }
}

这是发布请求的样子

POST http://localhost:xxxxx/Donor/api/Donors/EditDonor HTTP/1.1
Content-Length: 477
Cache-Control: no-cache
Content-Type: application/json;charset=UTF-8
Accept: */*
...

{"Id":12,"UserId":"donor9@abc.com","FirstName":"firstname9c","MiddleName":"M","LastName":"lastname9","Gender":"Male","MobileNumber":"7777777777","BloodGroup":"A+ve","OfficeLocality":{"Id":2,"Name":"Malad"},"ResidenceLocality":{"Id":2,"Name":"Malad"},"Organization":"organization9","Designation":"designation9","TimesDonated":1,"DateLastDonated":"Mon Dec 01 00:00:00 GMT+05:30 2014","LastDonatedAt":"Hosp 1","IsSDPDonor":false,"IsIntrestedDonor":false,"Comments":"Some Comment"}

问题在于 Donor 对象是空的(不是 null 而是空的,没有应用于 Donor 的属性的值)。

如果我更改 Donor 对象并使用具有相同属性但没有任何继承的 Data Transfer Object (DonorDO),则属性会正确填充到该 Data 对象中.例如,捐赠者数据对象如下所示。

//Plain Data Transfer Object without inheritance
public class DonorDO {
    public long Id { get; set; }
    public string AlternateMobileNumber { get; set; }
    ...
}

为什么 DonorDO 可以正确绑定其属性值,而 Donor 实体对象保持为空且未绑定任何属性。是否与继承或其他问题有关。

【问题讨论】:

  • 也许问题出在你的 Json 格式上。尝试使用一些仅包含 Id 和 AlternateMobileNumber 属性的简单 Json 吗?顺便说一句,您可以删除 FromBody 属性,因为 Donor 不是原始类型,因此它会自动从 body 中获取
  • 感谢您指出 FromBody。我尝试按照您的建议仅发送几个字段而不是完整的 JSON,但是 Donor 对象的属性值全部为 null 或默认值。输入 JSON 中的任何值都不会应用于 Donor 对象。
  • 你能在哪里解决这个问题?
  • @jarz 我最后使用了 DonorDO 对象。我不记得为什么数据对象有效,而不是实体对象。

标签: asp.net-web-api model-binding asp.net-web-api2


【解决方案1】:

我注意到您正在发布到“http://localhost:xxxxx/Donor/api/Donors/EditDonor”这是错误的,您需要发布到“http://localhost:xxxxx/api/Donors” " (您只需 POST 到控制器基地址,控制器名称应在“api”之后而不是之前)。

此代码 100% 有效:

using System.Net;
using System.Net.Http;
using System.Web.Http;

//[Authorize]
public class DonorsController : ApiController
{

    [HttpGet]
    public Donor Get(int id)
    {
        return new Donor
        {
            Id = id,
            AlternateMobileNumber = "0000",
        };
    }

    //POST: api/Donors/EditDonor
    [HttpPost]
    public HttpResponseMessage EditDonor([FromBody] Donor donor)
    {
        return new HttpResponseMessage(HttpStatusCode.OK);
    }
}

public abstract class User
{
    public long Id { get; set; }
}

public class Donor : User
{
    public string AlternateMobileNumber { get; set; }
}

现在,我使用 fiddler 调用了这个方法,如下图所示,在控制器端,您可以看到传递的供体参数。

希望这会有所帮助。

【讨论】:

  • 感谢您的努力,但我正在使用虚拟目录 /Donor。所以我的 POST 网址是正确的。有一个基础网站 www.somewebsite.org,我的应用程序作为一个单独的应用程序运行,带有 /Donor 虚拟目录,即使用 url www.somewebsite.com/donor。我有其他路径,如 localhost:xxxxx/Donor/api/Donors/SearchDonor 正常工作,使用默认参数和模型绑定。
  • 没问题,把fiddler url里的url改一下试试代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-03
  • 2012-03-23
  • 1970-01-01
  • 2019-04-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多