JQuery ajax post 控制器中的参数为空

JQuery ajax post parameters null in controller

我有一个 ajax POST 请求:

$.ajax({
    url: "/api/EmmaWeb/SaveFavourite", //window.location.pathname + "?handler=favourite", //"/it/Umbria/vocabolo-menicaglie-6?handler=favourite",
    type: "POST",
    headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]', $form).val() },
    //contentType: "application/jsonrequest; charset=utf-8",
    //contentType: 'application/json',
    //dataType: "json",
    data: JSON.stringify({ isFavourite: $inputIsFavourite.val().toLowerCase(), propertyUnitSlug: $PropertyUnitSlug.val() }),
    cache: false
}).done(function (resp) {
    console.log("done", resp);
});

我的控制器:

[ApiController]
[Route("/api/[controller]")]
public class EmmaWebController : Controller
{
    [HttpPost]
    [Route("[action]")]
    public async Task<IActionResult> SaveFavouriteAsync(bool isFavourite, string propertyUnitSlug)
    {
        // DO Something

        return new JsonResult(new
        {
            // Something
        });
    }
}

我在控制器中执行了我的操作,但参数始终为空。我尝试添加 [FromBody] 但出现 415 错误

FromBodyAttribute只能使用一次,因为它使用了整个请求体。

有几种解决方法可以解决此问题:

使用包装器class

public class SaveFavouriteRequest 
{
   public bool IsFavourite { get; set; }
   public string PropertyUnitSlug { get; set; }
}
public async Task<IActionResult> SaveFavouriteAsync([FromBody]SaveFavouriteRequest requestData)
{
   var x = requestData.IsFavourite;
}

使用JObject

public async Task<IActionResult> SaveFavouriteAsync([FromBody]JObject requestData)
{
   var x = requestData["isFavourite"].ToObject<bool>();
}

使用dynamic

public async Task<IActionResult> SaveFavouriteAsync([FromBody]dynamic requestData)
{
   var x = JsonConvert.DeserializeObject<bool>(requestData.isFavourite.ToString());
}

ToString() 可能需要 .ToLower()


没有FromBody

的备选方案

Request.Body

上使用 JObject.ParseStreamReader
public async Task<IActionResult> SaveFavouriteAsync()
{
    using var reader = new StreamReader(Request.Body, Encoding.UTF8);
    var requestBody = await reader.ReadToEndAsync();
    var requestData = JObject.Parse(requestBody);
    var x = JsonConvert.DeserializeObject<bool>(requestData["isFavourite"].ToString().ToLower());
}

Request.Body

上使用 JObject.LoadAsyncJsonTextReader
public async Task<IActionResult> SaveFavouriteAsync()
{
    using var reader = new HttpRequestStreamReader(Request.Body, Encoding.UTF8);
    using var jsonReader = new JsonTextReader(reader);
    var requestData = await JObject.LoadAsync(jsonReader);
    var x = JsonConvert.DeserializeObject<bool>(requestData["isFavourite"].ToString().ToLower());
}

我解决了从控制器中删除 [ApiController] 属性的问题,这是 ajax:

$.ajax({
    url: "/api/EmmaWeb/SaveFavourite", //window.location.pathname + "?handler=favourite", //"/it/Umbria/vocabolo-menicaglie-6?handler=favourite",
    type: "POST",
    headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]', $form).val() },
    //contentType: "application/jsonrequest; charset=utf-8",
    //dataType: "json",
    //contentType: 'application/json',        
    //dataType: "json",
    data: { "isFavourite": $inputIsFavourite.val(), "propertyUnitSlug": $PropertyUnitSlug.val() },
    cache: false
})