You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core MVC中使用jQuery.ajax传递模型与额外参数至控制器的绑定问题

ASP.NET Core MVC中使用jQuery.ajax传递模型与额外参数至控制器的绑定问题

我看了你的代码,发现几个关键问题导致参数没有正确绑定,咱们一步步来解决:

一、先修正JavaScript里的两个小错误

1. updateModel函数没有返回模型

你的updateModel函数里填充了全局的model变量,但函数本身没有返回值,执行model = updateModel()后,model会变成undefined,这直接导致请求数据是空的!

修正这个函数,最后加上return model;:

var model = {}; //global variable
function updateModel() {
    for(const element of document.querySelectorAll("input.account-property-input")) {
        if(element instanceof HTMLInputElement && typeof element.name === "string" && element.name.trim().length > 0) {
            model[element.name] = element.value;
        }
    }
    let checkbox = document.querySelector("input#enable-two-factor-checkbox");
    if(checkbox instanceof HTMLInputElement) {
        model[checkbox.name] = checkbox.checked;
    }
    if(checkbox.checked) {
        radio = document.querySelector("input#two-factor-by-phone-radio");
        model.TwoFactorMethod = radio.checked ? "TwoFactorByPhoneNumber" : "TwoFactorByEmail";
    }
    // 新增:返回填充好的模型
    return model;
}

2. 修正Ajax请求的数据格式

你设置了contentType: "application/json; charset=utf-8",但直接传递了JavaScript对象{ model: model, contactType: contactType },jQuery默认会把对象编码成form-urlencoded格式,和你指定的contentType不匹配,导致后端无法解析JSON数据。

需要用JSON.stringify()把数据转成JSON字符串:

model = updateModel();
const urlAction = window.location.origin + "/UserAccount/ConfirmContact";
const jqXHR = $.ajax({
    method: "POST",
    url: urlAction,
    // 把对象序列化为JSON字符串
    data: JSON.stringify({ model: model, contactType: contactType }),
    contentType: "application/json; charset=utf-8"
});

await jqXHR?.then( async function(data, textStatus, jqxhr) {
    alert(`request to ${urlAction} is successed`);
}, function(jqxhr, textStatus, errorThrown) {
    alert(`request to ${urlAction} is failed; status: ${textStatus}; error: ${errorThrown}`);
});

二、修正控制器的参数绑定逻辑

ASP.NET Core中,[FromBody]特性只能用于一个参数(因为请求体只能读取一次),所以直接写两个参数AccountViewModel model, ContactType contactType的话,后端无法同时从JSON请求体中绑定两个参数。这里有两种解决方案:

方案一:创建一个包装类(推荐)

新建一个DTO类,把需要传递的模型和额外参数包装在一起:

public class ConfirmContactRequest
{
    public AccountViewModel Model { get; set; }
    public ContactType ContactType { get; set; }
}

然后修改控制器的Action,用这个DTO作为参数,并加上[FromBody]特性:

[HttpPost]
public async Task<IActionResult> ConfirmContact([FromBody] ConfirmContactRequest request)
{
    if(request?.Model != null)
    {
        if(request.ContactType == ContactType.PhoneNumber)
        {
            if(await PhoneConfirmationService.SendVerificationCode(request.Model))
            {
                request.Model.PhoneConfirmationState = ContactConfirmationState.AwaitingConfirmation;
            }
        }
        else
        {
            if(await EmailConfirmationService.SendVerificationCode(HttpContext, request.Model))
            {
                request.Model.EmailConfirmationState = ContactConfirmationState.AwaitingConfirmation;
            }
        }
    }
    return View("Register", request?.Model ?? new AccountViewModel());
}

方案二:将额外参数放在URL查询字符串中

如果不想创建新的类,可以把contactType作为URL的查询参数传递,模型从请求体绑定:

修改JavaScript的URL拼接:

// 把contactType拼到URL的查询参数里
const urlAction = `${window.location.origin}/UserAccount/ConfirmContact?contactType=${contactType}`;
const jqXHR = $.ajax({
    method: "POST",
    url: urlAction,
    // 只传递model对象,不需要包装
    data: JSON.stringify(model),
    contentType: "application/json; charset=utf-8"
});

然后修改控制器的Action,给contactType加上[FromQuery]特性:

[HttpPost]
public async Task<IActionResult> ConfirmContact([FromBody] AccountViewModel model, [FromQuery] ContactType contactType)
{
    // 原有逻辑不变
    if(model != null)
    {
        if(contactType == ContactType.PhoneNumber)
        {
            if(await PhoneConfirmationService.SendVerificationCode(model))
            {
                model.PhoneConfirmationState = ContactConfirmationState.AwaitingConfirmation;
            }
        }
        else
        {
            if(await EmailConfirmationService.SendVerificationCode(HttpContext, model))
            {
                model.EmailConfirmationState = ContactConfirmationState.AwaitingConfirmation;
            }
        }
    }
    return View("Register", model ?? new AccountViewModel());
}

最后验证一下

做完这些修改后,再测试请求:

  1. 确保updateModel正确返回填充后的模型
  2. 请求数据是正确的JSON格式
  3. 控制器参数能正确绑定到传递的数据

这样应该就能解决参数没有初始化的问题了。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 10:12:57