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

如何在ASP.NET Core多控制器中复用表单提交方法并处理验证错误?

复用表单提交方法并保留原URL的解决方案

方案一:改进控制器继承逻辑,动态返回原视图

1. 修改分部视图的表单目标

把表单的asp-controller改为当前页面所在的控制器,不要写死Base:

@model UserModel

<form asp-controller="@ViewContext.RouteData.Values["controller"]" 
      asp-action="ScheduleDemo" 
      method="post" 
      asp-antiforgery="true">
    <p>
        <label asp-for="@Model.UserName">UserName</label><br />
        <input type="text" asp-for="@Model.UserName" />
        <span asp-validation-for="UserName"  class="text-danger" style="color: red;"></span>
    </p>
    <p>
        <label asp-for="@Model.Age">Age</label><br />
        <input asp-for="@Model.Age" />
        <span asp-validation-for="Age" class="text-danger" style="color: red;"></span>
    </p>
    <p>
        <label asp-for="@Model.City">City</label><br />
        <input type="text" asp-for="@Model.City" />
    </p>
    <input type="submit" value="Send" />
</form>

这样表单会提交到当前页面的控制器(Home/Additional),不会跳转到Base的路由。

2. 优化BaseController的提交方法

验证失败时返回当前控制器的Index视图,保留原URL的同时传递错误模型:

public class BaseController : Controller
{
    [HttpPost]
    public IActionResult ScheduleDemo(UserModel model)
    {
        if (ModelState.IsValid)
        {
            // 执行邮件发送等业务逻辑
            // 成功后重定向回原页面,避免表单重复提交
            return RedirectToAction("Index", ControllerContext.ActionDescriptor.ControllerName);
        }

        // 验证失败,返回当前控制器的Index视图,错误模型会自动传递给分部视图
        return View("Index", model);
    }
}

由于Home和Additional都继承自Base,ControllerContext.ActionDescriptor.ControllerName会自动获取当前控制器名称,返回对应视图后URL保持不变,分部视图能正常显示验证错误。

方案二:AJAX无刷新提交(体验更优)

如果希望页面不刷新,仅更新表单区域,可采用AJAX提交:

1. 修改分部视图添加AJAX逻辑

@model UserModel

<div id="scheduleDemoContainer">
    <form id="demoForm" asp-antiforgery="true">
        <p>
            <label asp-for="@Model.UserName">UserName</label><br />
            <input type="text" asp-for="@Model.UserName" />
            <span asp-validation-for="UserName"  class="text-danger" style="color: red;"></span>
        </p>
        <p>
            <label asp-for="@Model.Age">Age</label><br />
            <input asp-for="@Model.Age" />
            <span asp-validation-for="Age" class="text-danger" style="color: red;"></span>
        </p>
        <p>
            <label asp-for="@Model.City">City</label><br />
            <input type="text" asp-for="@Model.City" />
        </p>
        <input type="submit" value="Send" />
    </form>
</div>

@section Scripts {
    <script>
        $(document).ready(function() {
            $("#demoForm").submit(function(e) {
                e.preventDefault();
                var formData = $(this).serialize();
                var submitUrl = '@Url.Action("ScheduleDemo")';

                $.post(submitUrl, formData)
                    .done(function() {
                        alert("提交成功");
                        $("#demoForm")[0].reset();
                    })
                    .fail(function(xhr) {
                        // 验证失败时,用返回的分部视图替换原表单区域
                        $("#scheduleDemoContainer").html(xhr.responseText);
                    });
            });
        });
    </script>
}

2. 调整BaseController方法

验证失败返回分部视图,成功返回状态提示:

public class BaseController : Controller
{
    [HttpPost]
    public IActionResult ScheduleDemo(UserModel model)
    {
        if (ModelState.IsValid)
        {
            // 执行业务逻辑
            return Ok();
        }

        // 验证失败返回带错误模型的分部视图
        return PartialView(@"~/Views/Shared/Partial/ScheduleDemo.cshtml", model);
    }
}

这种方式完全避免页面跳转,仅更新表单区域,同时实现代码复用。

补充提示

  • 确保UserModel配置了正确的验证特性(如[Required]、[Range]等),才能让ModelState正确捕获错误。
  • 方案一中的重定向逻辑可根据需求调整,比如用TempData传递成功提示信息。

内容的提问来源于stack exchange,提问作者Artem Mazurov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 12:45:37