Ошибка при создании RenderPartialAsync, проблема в контроллере?

#asp.net #asp.net-mvc #asp.net-core

#asp.net #asp.net-mvc #asp.net-core

Вопрос:

Существует контроллер индекса, в нем я связываю данные из базы данных с modelview, и мое представление собирает пользовательские данные и отображает их. И соответственно ниже я прикреплю PartialView

 public class CustomerController : Controller
{
    private ICustomerRepository _customerRepository;
    public CustomerController(ICustomerRepository customerRepository)
    {
        _customerRepository = customerRepository;
    }
    [HttpGet]
    public IActionResult Index()
    {
      IEnumerable<CustomerViewModel> customers =
    _customerRepository.GetAllCustomers().Select(s => new
    CustomerViewModel
    {
        CustomerId = s.CustomerId,
        Name = s.Name,
        Adress = s.Adress
    });
        return View("Index", customers);
    }
    [HttpGet]
    public IActionResult Create()
    {
        return Redirect("Index");
    }
}

@model IEnumerable<CustomerViewModel>
<h2>Create Customer</h2>
@{
await Html.RenderPartialAsync("Create");
}
<table class="table">
@Html.DisplayNameFor(model => model.Name)
@foreach (var item in Model)
{
            @Html.DisplayFor(modelItem => item.Name)
}
</table>
 

Это сам PartialView:

 @model CustomerViewModel
        <div class="col-md-4">
            <form asp-action="Create" asp-controller="Customer">

                <div class="form-group">
                    <label asp-for="Name" class="control-label"></label>
                    <input type="text" asp-for="Name" class="form-control" />
                </div>
 

При запуске приложения возникает ошибка:

Исключение InvalidOperationException: элемент модели, переданный в ViewDataDictionary, имеет тип ‘System.Linq.Enumerable SelectEnumerableIterator` 2[Store.DAL.Entity.Клиент, Store.Web.ViewModels.CustomerViewModel]’, но для этого экземпляра ViewDataDictionary требуется элемент модели типа ‘Store.Web.ViewModels. CustomerViewModel

Если PartialView поместить на отдельную страницу, просто чтобы создать ссылку на представление, все будет отображаться, и ошибки не будет. Может быть, все дело в том, как я переопределяю данные в контроллере для CustomerViewModel? Кто занимался этим?

Ответ №1:

Что происходит

В вашем коде вы не предоставляете своему представлению модель, которую оно ожидает.

Если вы используете Html.RenderPartialAsync(viewName) , вы автоматически передаете всю модель из основного представления в частичное. Поскольку основное представление имеет тип модели IEnumerable<CustomerViewModel> — это то, что передается вашему частичному представлению.

Решения

  1. Используйте отдельную страницу для создания объектов вместо повторного использования той же страницы для отображения существующих
  2. Сделайте вашу модель более сложной, чтобы ее можно было использовать для обоих представлений, и используйте перегрузку Html.RenderPartialAsync(string viewName, object model) для правильной передачи модели.

Для решения # 2 пример кода может быть:

Новый класс

 public class CustomerListViewModel
{
    IEnumerable<CustomerViewModel> existingCustomers;
    CustomerViewModel newCustomer;
}
 

Контроллер

 [HttpGet]
public IActionResult Index()
{
    IEnumerable<CustomerViewModel> customers =
    _customerRepository.GetAllCustomers().Select(s => new
    CustomerViewModel
    {
        CustomerId = s.CustomerId,
        Name = s.Name,
        Adress = s.Adress
    });
    CustomerListViewModel model = new CustomerListViewModel
    {
       existingCustomers = customers.AsEnumerable();
       newCustomer = new CustomerViewModel();
    }
    return View("Index", model);
}
 

Основной вид

 @model CustomerListViewModel
<h2>Create Customer</h2>
@{
await Html.RenderPartialAsync("Create", Model.newCustomer);
}
<table class="table">
@foreach (var item in Model.existingCustomers)
{
   <tr>
       <td>@Html.DisplayFor(item => item.Name)</td>
   </tr>
}
</table>