ASP .NET Core 5 Razor Pages:如何正确使用局部视图并验证其模型状态?

Posted

技术标签:

【中文标题】ASP .NET Core 5 Razor Pages:如何正确使用局部视图并验证其模型状态?【英文标题】:ASP .NET Core 5 Razor Pages: how to properly use Partial View and validate it's model state? 【发布时间】:2021-07-11 03:16:44 【问题描述】:

我正在使用 ASP .NET Core 5 Razor 页面。

我的目标是拥有一组可以在多个页面上使用的部分视图(出于可重用性目的)。每个 Partial View 都有一个带有自己的自定义 post 事件处理程序的表单(它将由包含此 Partial View 的页面的代码隐藏处理)。

注意有些页面可能包含两个甚至更多不同的局部视图!而且我需要验证部分视图模型彼此独立(在两个单独的自定义事件处理程序中)。

这是我今天使用的简化代码。 部分视图模型(包含用户的一些数据):

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();
    

_UserPartial.cshtml(显示该用户数据):

@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 总是 valid 即使 NameSurname 为空: 看起来 UserModel 根本没有验证。

而且我有一种强烈的感觉,我正在以错误的方式使用局部视图(而不是它们应该使用的方式)。

那么我的代码有什么问题?如何正确使用局部视图并验证其模型状态?任何帮助表示赞赏。

【问题讨论】:

【参考方案1】:

您不需要为局部视图创建页面模型。只需将其添加为 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>

【讨论】:

某些页面可以包含两个甚至更多不同的部分视图 - 我已经更新了我的问题。因此,除了public User userModel get; set; ,它还可以是我主页上的public Message messageModel get; set; 。而且我需要验证这两个模型彼此独立(在两个单独的自定义事件处理程序中)。我的示例是,您提供的 ModelState.IsValid 只有在 both 部分视图模型(userModel 和 messageModel)都有效时才为 true。有没有办法确定例如只有 userModel 字段是正确的? 好的,我更新了我的答案。他们确实验证了所有模型,但是您可以在处理程序中做一些事情,首先清除模型状态,然后验证指定模型。 谢谢。这正是我所需要的。

以上是关于ASP .NET Core 5 Razor Pages:如何正确使用局部视图并验证其模型状态?的主要内容,如果未能解决你的问题,请参考以下文章

缩短asp.net core 5 Razor页面中区域的路径

ASP .NET Core 5 Razor Pages:如何正确使用局部视图并验证其模型状态?

自动完成在 Visual Studio Code 中的 ASP.NET Core 5 Razor Tag Helper 中不起作用

[Asp.Net Core]MVC_Razor布局

[Asp.Net Core]MVC_Razor布局

覆盖 asp.net core razor 页面中的 razor 视图