Asp.Net MVC - 视图模型空值



我制作了一个网络应用程序,您可以在其中按客户端ID进行搜索,然后在该客户端上添加订单。索引操作方法将选定的客户端分配给视图模型(vm.AllClients(。订单表当然包含有关客户端的信息。在 Insert 方法中,我想使用有关所选客户端的信息,但现在 vm.AllClients 返回 null。

在调试期间,vm.AllClients 填充了一个客户端对象,因为它应该在运行第一个方法期间。当第二种方法运行时,vm.AllClients 为空。

我尝试将搜索字符串保存为变量并在 db 中找到它(不是一个很好的解决方案(,但在运行第二种方法期间该变量也是空的。还尝试将所选客户端另存为视图模型中的客户端对象,仍然没有骰子。

添加控制器

using MainWeb.Models;
public class AddController : Controller
{
OrderEntities db = new OrderEntities();// New instance of db.
ViewModel vm = new ViewModel();//New instance of viewmodel

[HttpPost]
public ActionResult Index(string searchTerm)
{
if (string.IsNullOrEmpty(searchTerm))
{
vm.AllClients = new List<Client>();
}
else
{
vm.AllClients = db.Clients.Where(x => 
x.RefNo.ToString().Equals(searchTerm)).ToList();
foreach (Client client in vm.AllClients)
{
vm.ThisClient = client;//Attempt at a different solution
break;
}
}
return View(vm);
}

public ActionResult InsertOrder(FormCollection form)
{
Order order = new Order();
order.ClientID = vm.AllClients[0].ID;//Here is where the error gets thrown
return RedirectToAction("Index");
}

视图

@model MainWeb.Models.ViewModel
<div class="card border-primary mb-3 card-client" style="max-width: 40rem;">
<div class="card-header">Legg til</div>
<div class="card-body">
<div class="editor-label">
<table>
@using (Html.BeginForm("Test", "Add", FormMethod.Post))
{ 
<tr>
<td>@Html.Label("Velg Prosjekt:")</td>
</tr>
<tr>
<td>
@Html.DropDownList("fromDBProjects", (IEnumerable<SelectListItem>)ViewData["DBProjects"], new { @class = "form-control" })
</td>
</tr>
<tr>
<td>@Html.Label("Velg Produkt:")</td>
</tr>
<tr>
<td>
@Html.DropDownList("fromDBProducts", (IEnumerable<SelectListItem>)ViewData["DBProducts"], new { @class = "form-control" })
</td>
</tr>
<tr>
<td>@Html.Label("Pris:")</td>
</tr>
<tr>
<td><input type="submit"  value="Submit" class="btn btn-primary" id="btn-search" /></td>
</tr>
}
</table>
</div>
</div>
</div>
</div>
}

视图模型

namespace MainWeb.Models
{
public class ViewModel
{
public List<Client> AllClients { get; set; } 
public Client ThisClient { get; set; }
}
}

错误:

Object reference not set to an instance of an object

一般来说,我认为您正在尝试编写一个新的 asp.net Web 应用程序。但是您应该考虑使用 asp.net 核心。这个框架是 asp.net mvc 的后续,你不应该开始编码 asp.net 核心 mvc 而不是完整的框架。这已被弃用,将被 asp.net 核心 mvc 取代

我想你应该先从 MS 做 mvc 教程。为了更好地了解一切是如何工作的。 https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/?view=aspnetcore-2.2

但是现在回答您的问题:您的示例中存在几个问题:

  1. ViewModel 不应该是一个中心类。 在您的控制器操作中创建它,因为每个 Web 请求都会获得控制器的新实例!
  2. 当您点击"插入顺序"时 - 为新请求新创建控制器。这意味着您获得了控制器的新实例,并且您的视图模型再次为空
  3. 你的
  4. cshtml永远不会点击你的"插入订单">
  5. InsertOrder 可以将表单集合直接映射到类中。
  6. 次要:你不应该用表格来布局你的html - 参见:为什么不使用表格在HTML中进行布局?

您的控制器应如下所示

public class AddController : Controller
{
OrderEntities db = new OrderEntities();// New instance of db.

[HttpPost]
public ActionResult Index(string searchTerm)
{
var vm = new ViewModel();
if (string.IsNullOrEmpty(searchTerm))
{
vm.AllClients = new List<Client>();
}
else
{
vm.AllClients = db.Clients.Where(x => 
x.RefNo.ToString().Equals(searchTerm)).ToList();
foreach (Client client in vm.AllClients)
{
vm.ThisClient = client;//Attempt at a different solution
break;
}
}
return View(vm);
}
[HttpPost]
public ActionResult InsertOrder(ViewModel vm)
{
Order order = new Order();
order.ClientID = vm.AllClients[0].ID;//Here is where the error gets thrown
return RedirectToAction("Index");
}

您的视图应将表单设置为:

@using (Html.BeginForm("InsertOrder", "Add", FormMethod.Post))

每个请求都会获得一个新的控制器实例,因此不能使用全局 Viewmodel 变量。如果要在控制器操作之间进行通信ViewData请使用对象,或者只是将数据发送到客户端并通过FormCollectionViewModel类获取数据。

最新更新