.NET core MVC, использующий платформу EF — Передача данных с одного контроллера на другой

#c# #asp.net-mvc #entity-framework #asp.net-core #entity-framework-core

Вопрос:

Я впервые занимаюсь разработкой веб-приложений с использованием ASP.NET Основной MVC с EF. У меня есть две таблицы(таблица клиентов и Инвентарная таблица) в базе данных SQL Server, я создал Scaffold-DbContext и сгенерировал Модели/Контроллеры и представления для обеих таблиц. Мое требование состоит в том, чтобы на странице Индекса клиентов для каждого клиента в таблице я добавил кнопку выбора, при нажатии на эту кнопку выбора мне нужно передать данные выбранного клиента контроллеру инвентаризации и показать выбор клиента в верхней части страницы Индекса инвентаризации, а ниже я показываю сетку с таблицей инвентаризации.

Я использую здесь временные данные. В таблице клиентов я добавил кнопку выбрать

 <td>
 <a asp-action="passToInventory" asp-route-id="@item.CustomerId">Select</a>
</td>
 

CustomersController

 public async Task<IActionResult> passToInventory(int? id)
 {
   if (id == null)
   {
     return NotFound();
   }
   Customer customer_data = await _context.Customers.FindAsync(id);

   TempData["custdata"] = customer_data;
   return RedirectToAction("Index", "Inventories");
 }
 

Теперь в контроллере инвентаризации в индексе я внес изменения, например, для доступа к переданным временным данным

 public async Task<IActionResult> Index()
 {
  Customer cust_data = TempData["custdata"] as Customer;
  return View(await _context.Inventories.ToListAsync());
 }
 

Я попытался создать модель, чтобы я мог использовать как Клиента, так и список запасов на странице Индекса запасов, как показано ниже

 public class CustomerInventoryCollectionDataModel
{
    public Customer CustomerData { get; set; }
    public List<Inventory> Inventorys { get; set; }
}
 

Я не смог получить данные, полученные на странице индекса инвентаризации

  @model IEnumerable<JAXSurplusMouseApp.Models.CustomerInventoryCollectionDataModel>
  
//show the selected customer data from the previous page 
  unable to access the customer data here and show it 

//table for the Inventory list 
<tbody>
    @foreach (var item in Model)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Inventorys.QuantityAvailable)
            </td>
         </tr>
     }
 

введите описание изображения здесь

Пожалуйста, подскажите мне, как я могу повторно отобразить обе модели в одном и том же представлении и показать их на одной странице. Любая помощь будет очень признательна

Ответ №1:

Экшен

 public async Task<IActionResult> Index()
 {
  Customer custData = TempData["custdata"] as Customer;
  var inventories =await _context.Inventories.ToListAsync();
  var model= new CustomerInventoryCollectionDataModel
{
   CustomerData = custData,
    Inventorys =inventories 
};

  return View(model);
 }
 

Вид

 @model JAXSurplusMouseApp.Models.CustomerInventoryCollectionDataModel
  
//show the selected customer data from the previous page 
//  using  @Model.CustData
 
@Html.DisplayFor(model => model.CustData.Name)

....and so on

//table for the Inventory list 
<tbody>
    @foreach (var item in Model.Inventorys)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.QuantityAvailable)
            </td>
         </tr>
     }
 

но я боюсь , что вам придется сериализовать клиента, поэтому мне кажется более эффективным использовать это

 public async Task<IActionResult> passToInventory(int? id)
 {
   if (id == null)
   {
     return NotFound();
   }
  
   return RedirectToAction("Index", "Inventories",new { id });

 }

 

Экшен

 public async Task<IActionResult> Index(int? id)
 {
 if(id==null) return ...error

  Customer custData =   await _context.Customers.FindAsync(id);
  var inventories =await _context.Inventories.ToListAsync();
  var model= new CustomerInventoryCollectionDataModel
{
   CustomerData = custData,
    Inventorys =inventories 
};

  return View(model);
 }
 

или, если вам по какой-либо причине необходимо использовать клиента TempData, вы можете использовать это в коде

 var customerData = await _context.Customers.FindAsync(id);

TempData["custdata"] =
System.Text.Json.JsonSerializer.Serialize( customerData;)

//index
 Customer custData = System.Text.Json.JsonSerializer.Deserialize<Customer> ( 
TempData["custdata"].ToString());
 

пс

Я не знаю, может быть, у вас есть больше кода в действии passToInventory, чем он опубликован, но то, как он выглядит сейчас, ИМХО, вы могли бы сразу перейти к индексации

 <td>
 <a asp-action="Index" asp-controller="Inventories" asp-route-id="@item.CustomerId">Select</a>
</td>
 

Комментарии:

1. Огромное спасибо. Я попробовал, но когда я нажимаю на кнопку «Выбрать», я получаю сообщение об ошибке, например InvalidOperationException: The 'Microsoft.AspNetCore.Mvc.ViewFeatures.Infrastructure.DefaultTempDataSerializer' cannot serialize an object of type 'JAXApp.Models.Customer'. Microsoft.AspNetCore.Mvc.ViewFeatures.Infrastructure.DefaultTempDataSerializer.Serialize(IDictionary<string, object> values)

2. @trx Я ожидал этого, поэтому обновляю свой ответ

3. Еще раз спасибо вам