如何在 ASP.NET Core 中正确使用 Partial View 并验证其模型状态

问题描述 投票:0回答:1

我正在使用 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();
    }
}

_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://learn.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 根本没有验证。

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

那么我的代码有什么问题呢?如何正确使用 Partial View 并验证其模型状态?

c# asp.net-core razor-pages
1个回答
7
投票

您不需要为部分视图提供页面模型。只需将其添加为 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();
}

索引.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>

© www.soinside.com 2019 - 2024. All rights reserved.