WebAPI 2 [FromBody] 参数未设置

本文关键字:参数 设置 FromBody WebAPI | 更新日期: 2023-09-27 18:34:28

我有一个应该是一个非常基本的场景......我觉得我以前已经做了 100 次,但由于某种原因,它决定不工作并将我的时间浪费在琐碎的事情上......

我正在使用带有属性路由的 WebAPI(喜欢它们(。

我正在尝试传入两个参数,一个来自正文,一个来自 Uri。它们都是基本类型...一个是布尔值,另一个是赞助商ID。

非常简单的服务签名...

[HttpPut]
[Route("adminAPI/sponsors/{sponsorID:long}/Enable")]
public HttpResponseMessage EnableSponsor([FromBody]Boolean enabled, [FromUri] Int64 sponsorID)
{
    HttpResponseMessage ret = null;
    // does stuff and populates the response
    return ret;
}

使用邮递员和高级REST客户端和JQuery/Chrome,我一直收到"错误请求"错误...

var request = function () {
    $.ajax({
        type: 'PUT',
        url: 'http://localhost:50865/adminAPI/Sponsor/23/Enable',
        data: { "enabled": true },
        contentType: "application/json"
    })
    .done(function (data, textStatus, jqXHR) {
        if ([200, 204, 304].indexOf(data.StatusCode) === -1) {
        } else {
        }
    })
    .fail(function (jqXHR, textStatus, errorThrown) {
    });
};

我收到以下错误...

参数

字典包含参数的空条目 方法的不可为空类型"系统.布尔值"的"启用" 'System.Net.Http.HttpResponseMessage EnableSponsorBanner(Boolean, Int64("中的"WEB.Admin.api.SponsorAPIController'.可选参数 必须是引用类型、可为 null 的类型或声明为 可选参数。

由于某种原因,[FromBody] 参数未随请求一起传递,从而导致错误。当我使参数为空时,请求会通过,但是,正如预期的那样,启用的参数为 NULL?

我把头撞在墙上...有什么想法吗?

溶液

我尝试简单地从 Web 服务调用中删除密钥,但没有成功。相反,我创建了一个数据传输对象 (DTO(,其中包含我可能单独发送到服务的基本数据类型。我可以使用它来传递此模型,以传递此请求以及将来发出的任何其他请求的简单值引用。

//
// The Data Transfer Object
    public class APIValueTypes
    {
        public Boolean booleanValue { get; set; }
        public Int64 longValue { get; set; }
        public String stringValue { get; set; }
        public DateTime dateValue { get; set; }
    }

由于服务知道它在寻找什么价值,它可以获取它需要的任何价值。

[HttpPut]
[Route("adminAPI/sponsors/{sponsorID:long}/Enable")]
public HttpResponseMessage EnableSponsor([FromBody]APIValueTypes enabled, [FromUri] Int64 sponsorID)
{
    HttpResponseMessage ret = null;
    Boolean isEnabled = enabled.booleanValue;
    // does stuff and populates the response
    return ret;
}

警告

但是,我现在必须承认,虽然我让它在我的 REST 工具中工作,但我无法让它在我的 JQuery 实现中工作。因此,虽然我的帖子已得到答复,但我在 JQuery ajax$ 方面遇到了另一个问题......即使我发送 DTO 对象,服务方法仍然收到空值而不是对象......(我怀疑的另一个帖子... - 叹息(

var request = function () {
    $.ajax({
        type: 'PUT',
        url: 'http://localhost/adminAPI/Sponsor/23/Enable',
        data: { "booleanValue": false },
        contentType: "application/json",
    })
    .done(function (data, textStatus, jqXHR) {
        console.log(data);
        if ([200, 204, 304].indexOf(data.StatusCode) === -1) {
        } else {
        }
    })
    .fail(function (jqXHR, textStatus, errorThrown) {
    });
};

警告解决方案

我发现简单地将 JSON 对象作为数据有效负载发送是行不通的。我必须"字符串化"数据才能将其序列化回APIValueType参数数据类型。因此,从 JQuery 对服务的调用现在看起来像......注意数据分配...

var request = function () {
    $.ajax({
        type: 'PUT',
        url: 'http://localhost/adminAPI/Sponsor/23/Enable',
        data: JSON.stringify({ "booleanValue": false }),
        contentType: "application/json",
    })
    .done(function (data, textStatus, jqXHR) {
        console.log(data);
        if ([200, 204, 304].indexOf(data.StatusCode) === -1) {
        } else {
        }
    })
    .fail(function (jqXHR, textStatus, errorThrown) {
    });
};

我希望有人能发现这个小旅程有用,当我在 6 个月内忘记它时,这篇文章仍然会在这里提醒我!!再次感谢!

WebAPI 2 [FromBody] 参数未设置

您遇到此问题是因为您没有以 Web API 期望 ASP.Net 格式发送数据。 ASP.net Web API 在处理字符串等值时需要一些特殊格式,值类型(整数、布尔值等(参数用FromBody属性标记。

您的 ASP.Net Web API 需要基元类型,但您正在发送一个对象{ enabled: true }然后它不会将其绑定到不是对象的enabled参数。

要使其正常工作,您必须使用以下代码作为jQuery ajax请求中的数据:

data: { "": true }

请注意,属性名称为空,它将告诉 jQuery 以这种格式=true发送数据。使用该格式,ASP.Net Web API 可以将其绑定到布尔参数。

要防止该问题,请始终使用 ViewModel。

我遇到了同样的问题,我从请求中删除了密钥,它已在我的变量中设置。

只需像这样删除启用:

var request = function () {
$.ajax({
    type: 'PUT',
    url: 'http://localhost:50865/adminAPI/Sponsor/23/Enable',
    data: { "": true },
    contentType: "application/json"
})
.done(function (data, textStatus, jqXHR) {
    if ([200, 204, 304].indexOf(data.StatusCode) === -1) {
    } else {
    }
})
.fail(function (jqXHR, textStatus, errorThrown) {
});

};

或者,您可以创建如下模型:

    public class Model
    {
        public bool Enabled { get; set; }
    }

然后:

[HttpPut]
[Route("adminAPI/sponsors/{sponsorID:long}/Enable")]
public HttpResponseMessage EnableSponsor([FromBody]Model model, [FromUri] Int64 sponsorID)
{
    HttpResponseMessage ret = null;
    // does stuff and populates the response
    return ret;
}

希望,它对你有用。