HttpPost 方法未从视图中获取正确的模型,还获取其他对象的 Null/Reference 对象错误 - MVC 5 C#
HttpPost method doesn't get the correct model from view, also get Null/Reference object errors with other objects - MVC 5 C#
我会边解释边解释这个问题。
我这里有这个观点
查看:
@model Project.Models.CheckoutItem
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Checkout - Project</title>
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<style type="text/css">
body{ margin-top:20px; }
</style>
</head>
<body>
@using (Html.BeginForm( ))
{
<div class="container">
<div class="row form-group">
<div class="col-xs-12">
<ul class="nav nav-pills nav-justified thumbnail setup-panel">
<li class="active">
<a href="#step-1">
<h4 class="list-group-item-heading">Step 1</h4>
<p class="list-group-item-text">Your Details</p>
</a>
</li>
<li class="disabled">
<a href="#step-2">
<h4 class="list-group-item-heading">Step 2</h4>
<p class="list-group-item-text">Delivery Method</p>
</a>
</li>
<li class="disabled">
<a href="#step-3">
<h4 class="list-group-item-heading">Step 3</h4>
<p class="list-group-item-text">Payment Information</p>
</a>
</li>
</ul>
</div>
</div>
<div class="panel panel-default">
<div class="panel-body">
Item: @Model.Item.ItemName
</div>
</div>
<div class="row setup-content" id="step-1">
<div class="col-xs-12">
<div class="col-md-12 well text-center">
<div class="col-md-4 col-md-offset-4">
@Html.ValidationSummary()
<!-- STEP 1-->
@Html.LabelFor(m => m.FirstName) @Html.TextBoxFor(m => m.FirstName, new { @class = "form-control", @required = "required" }) <br/>
@Html.LabelFor(m => m.LastName) @Html.TextBoxFor(m => m.LastName, new { @class = "form-control", @required = "required" })<br />
@Html.LabelFor(m => m.Email) @Html.TextBoxFor(m => m.Email, new { @class = "form-control", @required = "required" })<br />
@Html.LabelFor(m => m.PhoneNumber) @Html.TextBoxFor(m => m.PhoneNumber, new { @class = "form-control", @required = "required" })<br />
@Html.LabelFor(m => m.MsgOnCard) @Html.TextAreaFor(m => m.MsgOnCard, new { @class = "form-control" })<br />
<button id="activate-step-2" class="btn btn-primary" type="button">Next</button>
</div>
</div>
</div>
</div>
<div class="row setup-content" id="step-2">
<div class="col-xs-12">
<div class="col-md-12 well text-center">
<div class="col-md-4 col-md-offset-4">
<!-- STEP 2 -->
@Html.LabelFor(m => m.ShippingMeth) @Html.EnumDropDownListFor(m => m.ShippingMeth) <br/> <br/>
<div id="shippingDetails" class="disabled">
@Html.LabelFor(m => m.deliveryDetails.Street) @Html.TextBoxFor(m => m.deliveryDetails.Street, new { @class = "form-control" }) <br/>
@Html.LabelFor(m => m.deliveryDetails.City) @Html.TextBoxFor(m => m.deliveryDetails.City, new { @class = "form-control" }) <br/>
@Html.LabelFor(m => m.deliveryDetails.State) @Html.TextBoxFor(m => m.deliveryDetails.State, new { @class = "form-control" }) <br/>
@Html.LabelFor(m => m.deliveryDetails.Postcode) @Html.TextBoxFor(m => m.deliveryDetails.Postcode, new { @class = "form-control" }) <br/>
</div>
<button id="activate-step-3" class="btn btn-primary" type="button">Next</button>
</div>
</div>
</div>
</div>
<div class="row setup-content" id="step-3">
<div class="col-xs-12">
<div class="col-md-12 well text-center">
<div class="col-md-4 col-md-offset-4">
<!-- STEP 3 -->
@Html.LabelFor(m => m.Card.CardHolder) @Html.TextBoxFor(m => m.Card.CardHolder, new { @class = "form-control" }) <br />
@Html.LabelFor(m => m.Card.CardNumber) @Html.TextBoxFor(m => m.Card.CardNumber, new { @class = "form-control" }) <br />
<b>Card Expiry</b> <br/> <br/> @Html.TextBoxFor(m => m.Card.ExpMonth, new { @class = "form-control" }) / @Html.TextBoxFor(m => m.Card.ExpYear, new { @class = "form-control" }) <br />
@Html.LabelFor(m => m.Card.Cvc) @Html.TextBoxFor(m => m.Card.Cvc, new { @class = "form-control" }) <br />
<input type="submit" value="Pay" class="btn btn-success btn-lg" name="Model" />
</div>
</div>
</div>
</div>
</div>
现在发生的事情是。该页面应该有一个用于付款处理的提交按钮。它会发送用户尝试购买的当前商品(型号)(包括其名称、描述、价格等)以及其他付款信息、运输信息和个人详细信息。
因此 CheckoutItem 包含实际出售的物品以及客户和购买的其他详细信息等。
问题是,视图提交,代码立即转到该模型的无参数构造函数。
还有
// I put in the constructor to initialize those variables in the class.
Item = new ItemModel();
有人告诉我这是必需的,因为当它抓取信息时,它需要一个空的模型实例来填充视图中的信息。
无论如何,发生的事情是,模型(对于正在出售的商品)曾经是空的,在如上所示初始化之后,它现在显示了它的默认值,但它仍然没有被视图真正返回到控制器。所以价格为 0,名称和描述本身为 null 等。所有其他付款信息、个人信息等都已在 CheckoutItem 中成功发送。
另一个问题是这个。信用卡信息只是从 CheckoutItem 的返回变量传输到控制器中的本地变量,但是我们得到一个 Reference Object not Instance(类似的东西)错误,您可能很熟悉。虽然在 Controller 中可以看到,本地信用卡详细信息对象的实例已经在 HttpPost 方法中进行了初始化。
对于为什么会出现这些问题,我们将不胜感激。我确信我在某个地方做过一些愚蠢的事情并不太复杂。
非常感谢你们,你们已经帮助我们解决了这个项目中的一个问题!
在您看来,您使用模型的 Item
属性 的唯一地方是这里:
<div class="panel-body">
Item: @Model.Item.ItemName
</div>
显然这只是将其名称打印到 HTML。如果您不在 inside HTML 表单中包含这些数据,则您不可能期望在提交数据时取回任何值。
所以一种可能性是为它们设置隐藏字段:
@Html.HiddenFor(x => x.Item.ItemName)
@Html.HiddenFor(x => x.Item.ItemPrice)
@Html.HiddenFor(x => x.Item.ItemDescription)
...
现在,当您提交表单时,这些值将被发送到服务器。另一种可能性是使用项目 ID 从数据库中获取它们,就像您在 GET 操作中所做的一样。如果用户不应该修改他们的值,这是推荐的方法。
视图确实需要在与项目模型相关的 HTML 表单中隐藏字段,以便视图知道要提交给控制器的内容等,正如@Darin Dimitrov 所建议的:
@Html.HiddenFor(x => x.Item.ItemName)
@Html.HiddenFor(x => x.Item.ItemPrice)
@Html.HiddenFor(x => x.Item.ItemDescription)
...
eWay 支付 models/classes 返回空错误的另一个问题与它们在对象中包含对象这一事实有关。如果你说初始化对象 A,它也包含带有变量的对象 B,那么你需要在 A 中初始化对象 B 的实例,这样它就不是一个巨大的 NULL 值,而是一堆其他值。这听起来令人困惑,但如下所示:
CustomerPayment payment1 = new CustomerPayment();
现在 CustomerPayment 对象内部包含另一个对象,类型为 CreditCardDetails,名为 CardDetails。这还需要初始化,以便可以访问其变量并且整个对象不为空,如下所示:
payment1.CardDetails = new CreditCardDetails();
现在您实际上可以使用其中的东西并为它们赋值例如:
payment1.CardDetails.Number = 1234 1234 1234 1234;
没有返回空错误。
这是 eWay(我们的支付网关)的惰性编码,为我们提供了 类 具有无参数构造函数,这些构造函数不会初始化封装在其中的其他对象。
我会边解释边解释这个问题。
我这里有这个观点
查看:
@model Project.Models.CheckoutItem
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Checkout - Project</title>
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<style type="text/css">
body{ margin-top:20px; }
</style>
</head>
<body>
@using (Html.BeginForm( ))
{
<div class="container">
<div class="row form-group">
<div class="col-xs-12">
<ul class="nav nav-pills nav-justified thumbnail setup-panel">
<li class="active">
<a href="#step-1">
<h4 class="list-group-item-heading">Step 1</h4>
<p class="list-group-item-text">Your Details</p>
</a>
</li>
<li class="disabled">
<a href="#step-2">
<h4 class="list-group-item-heading">Step 2</h4>
<p class="list-group-item-text">Delivery Method</p>
</a>
</li>
<li class="disabled">
<a href="#step-3">
<h4 class="list-group-item-heading">Step 3</h4>
<p class="list-group-item-text">Payment Information</p>
</a>
</li>
</ul>
</div>
</div>
<div class="panel panel-default">
<div class="panel-body">
Item: @Model.Item.ItemName
</div>
</div>
<div class="row setup-content" id="step-1">
<div class="col-xs-12">
<div class="col-md-12 well text-center">
<div class="col-md-4 col-md-offset-4">
@Html.ValidationSummary()
<!-- STEP 1-->
@Html.LabelFor(m => m.FirstName) @Html.TextBoxFor(m => m.FirstName, new { @class = "form-control", @required = "required" }) <br/>
@Html.LabelFor(m => m.LastName) @Html.TextBoxFor(m => m.LastName, new { @class = "form-control", @required = "required" })<br />
@Html.LabelFor(m => m.Email) @Html.TextBoxFor(m => m.Email, new { @class = "form-control", @required = "required" })<br />
@Html.LabelFor(m => m.PhoneNumber) @Html.TextBoxFor(m => m.PhoneNumber, new { @class = "form-control", @required = "required" })<br />
@Html.LabelFor(m => m.MsgOnCard) @Html.TextAreaFor(m => m.MsgOnCard, new { @class = "form-control" })<br />
<button id="activate-step-2" class="btn btn-primary" type="button">Next</button>
</div>
</div>
</div>
</div>
<div class="row setup-content" id="step-2">
<div class="col-xs-12">
<div class="col-md-12 well text-center">
<div class="col-md-4 col-md-offset-4">
<!-- STEP 2 -->
@Html.LabelFor(m => m.ShippingMeth) @Html.EnumDropDownListFor(m => m.ShippingMeth) <br/> <br/>
<div id="shippingDetails" class="disabled">
@Html.LabelFor(m => m.deliveryDetails.Street) @Html.TextBoxFor(m => m.deliveryDetails.Street, new { @class = "form-control" }) <br/>
@Html.LabelFor(m => m.deliveryDetails.City) @Html.TextBoxFor(m => m.deliveryDetails.City, new { @class = "form-control" }) <br/>
@Html.LabelFor(m => m.deliveryDetails.State) @Html.TextBoxFor(m => m.deliveryDetails.State, new { @class = "form-control" }) <br/>
@Html.LabelFor(m => m.deliveryDetails.Postcode) @Html.TextBoxFor(m => m.deliveryDetails.Postcode, new { @class = "form-control" }) <br/>
</div>
<button id="activate-step-3" class="btn btn-primary" type="button">Next</button>
</div>
</div>
</div>
</div>
<div class="row setup-content" id="step-3">
<div class="col-xs-12">
<div class="col-md-12 well text-center">
<div class="col-md-4 col-md-offset-4">
<!-- STEP 3 -->
@Html.LabelFor(m => m.Card.CardHolder) @Html.TextBoxFor(m => m.Card.CardHolder, new { @class = "form-control" }) <br />
@Html.LabelFor(m => m.Card.CardNumber) @Html.TextBoxFor(m => m.Card.CardNumber, new { @class = "form-control" }) <br />
<b>Card Expiry</b> <br/> <br/> @Html.TextBoxFor(m => m.Card.ExpMonth, new { @class = "form-control" }) / @Html.TextBoxFor(m => m.Card.ExpYear, new { @class = "form-control" }) <br />
@Html.LabelFor(m => m.Card.Cvc) @Html.TextBoxFor(m => m.Card.Cvc, new { @class = "form-control" }) <br />
<input type="submit" value="Pay" class="btn btn-success btn-lg" name="Model" />
</div>
</div>
</div>
</div>
</div>
现在发生的事情是。该页面应该有一个用于付款处理的提交按钮。它会发送用户尝试购买的当前商品(型号)(包括其名称、描述、价格等)以及其他付款信息、运输信息和个人详细信息。
因此 CheckoutItem 包含实际出售的物品以及客户和购买的其他详细信息等。
问题是,视图提交,代码立即转到该模型的无参数构造函数。
还有
// I put in the constructor to initialize those variables in the class.
Item = new ItemModel();
有人告诉我这是必需的,因为当它抓取信息时,它需要一个空的模型实例来填充视图中的信息。
无论如何,发生的事情是,模型(对于正在出售的商品)曾经是空的,在如上所示初始化之后,它现在显示了它的默认值,但它仍然没有被视图真正返回到控制器。所以价格为 0,名称和描述本身为 null 等。所有其他付款信息、个人信息等都已在 CheckoutItem 中成功发送。
另一个问题是这个。信用卡信息只是从 CheckoutItem 的返回变量传输到控制器中的本地变量,但是我们得到一个 Reference Object not Instance(类似的东西)错误,您可能很熟悉。虽然在 Controller 中可以看到,本地信用卡详细信息对象的实例已经在 HttpPost 方法中进行了初始化。
对于为什么会出现这些问题,我们将不胜感激。我确信我在某个地方做过一些愚蠢的事情并不太复杂。
非常感谢你们,你们已经帮助我们解决了这个项目中的一个问题!
在您看来,您使用模型的 Item
属性 的唯一地方是这里:
<div class="panel-body">
Item: @Model.Item.ItemName
</div>
显然这只是将其名称打印到 HTML。如果您不在 inside HTML 表单中包含这些数据,则您不可能期望在提交数据时取回任何值。
所以一种可能性是为它们设置隐藏字段:
@Html.HiddenFor(x => x.Item.ItemName)
@Html.HiddenFor(x => x.Item.ItemPrice)
@Html.HiddenFor(x => x.Item.ItemDescription)
...
现在,当您提交表单时,这些值将被发送到服务器。另一种可能性是使用项目 ID 从数据库中获取它们,就像您在 GET 操作中所做的一样。如果用户不应该修改他们的值,这是推荐的方法。
视图确实需要在与项目模型相关的 HTML 表单中隐藏字段,以便视图知道要提交给控制器的内容等,正如@Darin Dimitrov 所建议的:
@Html.HiddenFor(x => x.Item.ItemName)
@Html.HiddenFor(x => x.Item.ItemPrice)
@Html.HiddenFor(x => x.Item.ItemDescription)
...
eWay 支付 models/classes 返回空错误的另一个问题与它们在对象中包含对象这一事实有关。如果你说初始化对象 A,它也包含带有变量的对象 B,那么你需要在 A 中初始化对象 B 的实例,这样它就不是一个巨大的 NULL 值,而是一堆其他值。这听起来令人困惑,但如下所示:
CustomerPayment payment1 = new CustomerPayment();
现在 CustomerPayment 对象内部包含另一个对象,类型为 CreditCardDetails,名为 CardDetails。这还需要初始化,以便可以访问其变量并且整个对象不为空,如下所示:
payment1.CardDetails = new CreditCardDetails();
现在您实际上可以使用其中的东西并为它们赋值例如:
payment1.CardDetails.Number = 1234 1234 1234 1234;
没有返回空错误。
这是 eWay(我们的支付网关)的惰性编码,为我们提供了 类 具有无参数构造函数,这些构造函数不会初始化封装在其中的其他对象。