问题描述
我使用的是 ASP .NET Core 5 Razor Pages。
我的目标是拥有一组可以在多个页面上使用的局部视图(用于可重用性目的)。每个局部视图都有一个带有自己自定义发布事件处理程序的表单(它将由包含该局部视图的页面的代码隐藏处理)。
注意有些页面可以包含两个甚至更多不同的局部视图!而且我需要相互独立(在两个单独的自定义事件处理程序中)验证部分视图模型。
这是我今天使用的简化代码。 部分视图模型(包含用户的一些数据):
public partial class User
{
[required]
public string Name { get; set; }
[required]
public string Surname { get; set; }
}
public class usermodel : PageModel
{
[BindProperty]
public User user { get; set; }
[TempData]
public string StatusMessage { get; set; }
public usermodel()
{
user = new User();
}
}
@model usermodel
<div class="row text-warning">
<div class="col-md-4">
<form method="post" asp-page-handler="UserEdited">
<div asp-validation-summary="ModelOnly"></div>
<div class="form-group">
<label asp-for="user.Surname" class="control-label"></label>
<input asp-for="user.Surname" class="form-control" />
<span asp-validation-for="user.Surname" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="user.Name" class="control-label"></label>
<input asp-for="user.Name" class="form-control" />
<span asp-validation-for="user.Name" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save user data" />
</div>
</form>
</div>
</div>
Index.cshtml(包含部分视图的主页):
@page
@model IndexModel
@{
ViewData["Title"] = "Main page";
}
@if (!String.IsNullOrWhiteSpace(@Model.StatusMessage))
{
<div class="text-center">
<h4 class="text-warning">@Model.StatusMessage</h4>
</div>
}
<div class="text-center" id="mainView">
<p>Some text in a main view</p>
<p>Some <a href="https://docs.microsoft.com/aspnet/core">link</a> in a main view.</p>
</div>
<div class="text-center" id="userPartialView">
@{await Html.RenderPartialAsync("_UserPartial",IndexModel.usermodel);}
</div>
//Some other Partial View (which contains some data for a message)
<div class="text-center" id="userPartialView">
@{await Html.RenderPartialAsync("_MessagePartial",IndexModel.messageModel);}
</div>
Index.cshtml.cs(主页的代码隐藏):
public class IndexModel : PageModel
{
public static usermodel usermodel { get; set; }
//A model for some other Partial View (which contains some data for a message)
public static MessageModel messageModel { get; set; }
[TempData]
public string StatusMessage { get; set; }
public IActionResult OnGet()
{
usermodel = new usermodel();
messageModel = new MessageModel();
return Page();
}
public IActionResult OnPostUserEdited()
{
if (!usermodel.ModelState.IsValid)
{
return Page();
}
StatusMessage = "User data was saved!";
return RedirectToPage();
}
}
问题是 usermodel.ModelState 总是有效,即使 Name 和 Surname 为空: 看起来 usermodel 根本没有验证。
而且我有一种强烈的感觉,我正在以错误的方式使用部分视图(而不是它们应该使用的方式)。
那么我的代码有什么问题?如何正确使用局部视图并验证其模型状态?任何帮助表示赞赏。
解决方法
您不需要为局部视图设置页面模型。只需将其添加为 Razor 视图即可。
索引.cshtml.cs
[BindProperty]
public User userModel { get; set; }
[BindProperty]
public Message messageModel { get; set; }
[TempData]
public string StatusMessage { get; set; }
public void OnGet()
{
userModel = new User();
}
public IActionResult OnPostUserEdited()
{
ModelState.Clear();
if (!TryValidateModel(userModel))
{
return Page();
}
StatusMessage = "User data was saved!";
return RedirectToPage();
}
public IActionResult OnPostMessageEdited()
{
ModelState.Clear();
if (!TryValidateModel(messageModel))
{
return Page();
}
StatusMessage = "Message data was saved!";
return RedirectToPage();
}
Index.cshtml:
<div class="text-center" id="userPartialView">
@{await Html.RenderPartialAsync("_UserPartial",Model.userModel);}
</div>
<div class="text-center" id="messagePartialView">
@{await Html.RenderPartialAsync("_MessagePartial",Model.messageModel);}
</div>