ASP.NET Core 2.1 Preview:表单如何引用替代模型?
在ASP.NET Core 2.1 Preview中为表单绑定替代模型的解决方案
这个场景我之前也碰到过——主视图模型带了一堆无关属性,但表单需要绑定另一个完全独立的模型,还要保留内置验证和标签助手的便利,其实有几种很实用的处理方式:
方法1:把替代模型作为主视图模型的子属性(最推荐)
如果可以修改现有视图模型,直接给它加一个表单需要的模型属性是最省心的做法:
首先更新你的主视图模型:
public class MainPageViewModel { // 原有的无关属性 public string PageTitle { get; set; } public IEnumerable<NewsItem> LatestNews { get; set; } // 表单专用的替代模型 public LoginFormViewModel LoginForm { get; set; } = new LoginFormViewModel(); }
然后在视图的表单里,直接用asp-for指定子属性路径就行,标签助手、验证、显示名称都会正常工作:
@model MainPageViewModel <form asp-action="SubmitLogin" method="post"> <div class="form-group"> <label asp-for="LoginForm.Username"></label> <input asp-for="LoginForm.Username" class="form-control" /> <span asp-validation-for="LoginForm.Username" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="LoginForm.Password"></label> <input asp-for="LoginForm.Password" class="form-control" /> <span asp-validation-for="LoginForm.Password" class="text-danger"></span> </div> <button type="submit" class="btn btn-primary">登录</button> </form>
控制器接收参数时,直接用替代模型类型就行:
[HttpPost] public IActionResult SubmitLogin(LoginFormViewModel loginForm) { // 处理表单逻辑 }
方法2:用局部视图解耦(无需修改主模型)
如果不想改动现有主视图模型,局部视图是完美的解耦方案:
- 先创建一个单独的局部视图(比如
_LoginForm.cshtml),顶部指定替代模型:
@model LoginFormViewModel <form asp-action="SubmitLogin" method="post"> <div class="form-group"> <label asp-for="Username"></label> <input asp-for="Username" class="form-control" /> <span asp-validation-for="Username" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Password"></label> <input asp-for="Password" class="form-control" /> <span asp-validation-for="Password" class="text-danger"></span> </div> <button type="submit" class="btn btn-primary">登录</button> </form>
- 在主视图里引用这个局部视图,同时传递替代模型实例:
@model MainPageViewModel <!-- 主视图原有内容 --> <h1>@Model.PageTitle</h1> <!-- 插入表单局部视图 --> <div class="login-box"> @await Html.PartialAsync("_LoginForm", new LoginFormViewModel()) </div>
这种方式下,局部视图里的所有标签助手和验证都完全独立绑定到替代模型,和主模型互不干扰。
方法3:直接在主视图声明模型变量(临时方案)
如果不想用局部视图也不想改主模型,还可以在主视图里直接声明替代模型变量,用传统Html助手绑定(标签助手默认绑定当前@model,所以这里得用Html助手):
@model MainPageViewModel @{ // 声明表单专用的模型变量 var loginModel = new LoginFormViewModel(); } <form asp-action="SubmitLogin" method="post"> <div class="form-group"> @Html.LabelFor(m => loginModel.Username) @Html.TextBoxFor(m => loginModel.Username, new { @class = "form-control" }) @Html.ValidationMessageFor(m => loginModel.Username, "", new { @class = "text-danger" }) </div> <div class="form-group"> @Html.LabelFor(m => loginModel.Password) @Html.PasswordFor(m => loginModel.Password, new { @class = "form-control" }) @Html.ValidationMessageFor(m => loginModel.Password, "", new { @class = "text-danger" }) </div> <button type="submit" class="btn btn-primary">登录</button> </form>
不过这种方式代码会显得杂乱,不如前两种优雅,只适合临时快速实现的场景。
内容的提问来源于stack exchange,提问作者Ritmo2k
相关产品推荐
相关产品推荐

