【问题标题】:Pass model to PartialAsync view (Razor, MVC)将模型传递给 PartialAsync 视图(Razor、MVC)
【发布时间】:2020-04-24 21:46:41
【问题描述】:

我有 AccountController.cs 有以下操作:

[HttpGet]
[AllowAnonymous]
public IActionResult Register()
 {
   ViewBag.Registration = GetRegistration();
   return View();
 }

ViewBag.Registration包含2个元素,没关系。

然后我得到了Registration.cshtml视图:

@model Registration <!-- this model I'm using for other form -->   
@{
    Layout = "_Layout";
}    
<!-- some code -->

@await Html.PartialAsync("AllRegistered")

AllRegistered.cshtml 应显示来自 ViewBag.Registration 的数据:

@model IEnumerable<Registration>

<table>
    <tr>
        <th>@Html.DisplayNameFor(m => m.Email)</th>
        <th>@Html.DisplayNameFor(m => m.City)</th>
    </tr>

    @if (Model != null && Model.Count() != 0)
    {
        @foreach (Registration registration in Model)
        {
            <tr>
                <th>@Html.DisplayFor(m => registration.Email)</th>
                <th>@Html.DisplayFor(m => registration.City)</th>
            </tr>
        }
     }
</table>

但是没有生成任何东西,我认为模型是空的。

【问题讨论】:

    标签: asp.net-mvc asp.net-core model-view-controller razor viewbag


    【解决方案1】:

    PartialAsync 方法包含一个包含模型的重载:

    Html.PartialAsync(string partialViewName, TModel model)

    您应该在该帮助程序中包含IEnumerable&lt;Registration&gt;(部分视图的模型)。

    如果 GetRegistrations() 返回那个 IEnumerable,你可以像这样定义局部视图:

    @await Html.PartialAsync("AllRegistered", (List&lt;Registration&gt;)ViewBag.Registration)

    【讨论】:

    • 这是正确的,但为什么要使用 ViewBag?这也应该有效:@await Html.PartialAsync("AllRegistered", GetRegistration()) 如果您需要多次调用 GetRegistration(),您也可以将其保存在页面上的变量中。
    【解决方案2】:

    虽然 Nathan 的回答完全正确,但将其作为视图组件会更合适。您要显示所有注册的事实是与此操作的目的无关的视图详细信息。因此,让操作负责检索数据要求它拥有不需要也不应该拥有的知识。

    相反,添加一个类,如:

    public class AllRegistrationsViewComponent : ViewComponent
    {
        private readonly RegistrationsService _service;
    
        public AllRegistrationsViewComponent(RegistrationService service)
        {
            _service = service;
        }
    
        public async Task<IViewComponentResult> InvokeAsync()
        {
            // logic behind `GetRegistrations()` here
            return View(registrations);
        }
    }
    

    这里对RegistrationsService 的引用只是您用来检索注册的任何方式,以显示如何将其注入到组件中。这可能是您的上下文或完全是其他东西。

    然后,使用以下命令创建视图 Views/Components/AllRegistrations/Default.cshtml

    @model IEnumerable<Registration>
    
    <table>
        <tr>
            <th>@Html.DisplayNameFor(m => m.Email)</th>
            <th>@Html.DisplayNameFor(m => m.City)</th>
        </tr>
    
        @if (Model != null && Model.Count() != 0)
        {
            @foreach (Registration registration in Model)
            {
                <tr>
                    <th>@Html.DisplayFor(m => registration.Email)</th>
                    <th>@Html.DisplayFor(m => registration.City)</th>
                </tr>
            }
         }
    </table>
    

    路径的AllRegistrations部分是基于视图组件的名称,没有ViewComponent部分,所以如果你命名不同,这里也调整一下。

    最后,在你看来:

    @await Component.InvokeAsync("AllRegistrations")
    

    那么,你的行动就可以专注于它的实际目的:

    [HttpGet]
    [AllowAnonymous]
    public IActionResult Register()
    {
        return View();
    }
    

    【讨论】:

      猜你喜欢
      • 2017-02-16
      • 2011-05-08
      • 2021-12-01
      • 2012-06-13
      • 2015-10-19
      • 2015-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多