首页 > 解决方案 > 将模型的属性作为参数传递给视图控制器

问题描述

我是 .NET 的实习生,我仍在学习阶段。关于 ViewComponent 和 Model 属性的问题,我遇到了一个十字路口

我有以下型号

namespace MVCHotel.Models
{
   public class Guest
   {
    public int ID { get; set; }

    [DisplayName("First Name")]
    [Required(ErrorMessage = "First name required")]
    public string FirstName { get; set; }

    [DisplayName("Last Name")]
    [Required(ErrorMessage = "Last name required")]
    public string LastName { get; set; }

    [DisplayName("Arrival Date")]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    [DataType(DataType.Date)]
    public DateTime ArrivalDate { get; set; }

    [DisplayName("Departure Date")]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    [DataType(DataType.Date)]
    public DateTime DepartureDate { get; set; }
   }
}

以下视图包含一个 ViewComponent ReservationsList,它显示行上的数据(名字、姓氏、到达日期、离开日期)

@model IEnumerable<MVCHotel.Models.Guest>

@{
    ViewData["Title"] = "Reservations";
}

<h2>@ViewData["Title"]</h2>

<div class="btn btn-default">
    <a asp-action="Create">Create new reservation</a>
</div>

<br />
<br />

<form asp-controller="Guests" asp-action="Reservations">
    <div>
        First Name: <input type="text" name="firstName" required>
        Last Name: <input type="text" name="lastName" required>
        <input id="submit" type="submit" value="Search" />
    </div>
</form>

<hr />

<div>
    @await Component.InvokeAsync("ReservationsList")
</div>

我想要做的是将firstNamelastName属性(我在表单的输入中设置((我有两个输入和一个根据输入过滤我的数据的按钮)))到 ViewComponent 但似乎Component.InvokeAsync 方法中的 @model.FirstName 或 @model.LastName 不起作用。

你有什么想法我该怎么做或者我应该寻找什么方法?非常感谢您的宝贵时间!

PS 是的,我可以通过控制器中的 ViewData 来做到这一点,但我的导师说有更好的方法是从模型中传递参数,但我没有找到任何具体的答案。

用解决方案编辑

最终这是在 View 中实现的解决方案。我使用带有 data-ajax 助手的 JQuery Unobtrusive AJAX 库来修改表单。

<form asp-controller="Guests" asp-action="SearchReservations" data-ajax="true" data-ajax-method="POST" data-ajax-update="#reservationsList" data-ajax-mode="replace" data-ajax-success="resultEmpty()">
    <div>
        First Name: <input type="text" name="firstName" required>
        Last Name: <input type="text" name="lastName" required>
        <input id="submit" type="submit" value="Search" />
    </div>
</form>

需要更改的另一件事是 ViewComponent 类,我必须将 Guest 模型对象作为参数传递(我之前传递了名字和姓氏)。

namespace MVCHotel.ViewComponents
{
    [ViewComponent(Name = "ReservationsList")]
    public class ReservationsListViewComponent : ViewComponent
    {
        private readonly MVCHotelContext _context;

        public ReservationsListViewComponent(MVCHotelContext context)
        {
            _context = context;
        }

        private Task<List<Guest>> GetReservationsAsync(Guest guest)
        {
            var reservations = from r in _context.Guest
                               select r;

            if (!String.IsNullOrEmpty(guest.FirstName) && !String.IsNullOrEmpty(guest.LastName))
            {
                reservations = reservations.Where(x => x.FirstName.Contains(guest.FirstName) && x.LastName.Contains(guest.LastName));
            }

            return reservations.ToListAsync();
        }

        public async Task<IViewComponentResult> InvokeAsync(Guest guest)
        {
            var items = await GetReservationsAsync(guest);
            return View(items);
        }
    }
}

我希望这对其他人也有帮助,在未来。

标签: jqueryasp.net-coreasp.net-core-mvcasp.net-ajaxasp.net-core-viewcomponent

解决方案


Component.InvokeAsync可以传递一个匿名对象,该对象最终将作为视图组件InvokeAsync方法的参数。换句话说:

@await Component.InvokeAsync("ReservationList", new { ... params here ... })

但是,您在这里尝试做的实际上是不可能的。您的模型、视图组件等都存在于服务器端,并且在将响应发送到客户端之前处理了所有内容。客户端(本例中为 Web 浏览器)接收响应并呈现所有 HTML 并将其显示给用户。只有在这一点上,用户才会在您的表单字段中输入一些内容。在此阶段,服务器根本不涉及,这意味着您不能将任何内容传递给您的视图组件。如果您需要再次涉及服务器,则必须使用 AJAX 向服务器提交新请求,可能会执行一些操作,例如发布这些表单字段的用户输入并让服务器返回部分 HTML 文档。然后,您可以通过 JavaScript 将 DOM 中的某些元素替换为新的 HTML。


推荐阅读