HttpPost方法没有从视图中得到正确的模型,也得到Null/引用对象错误与其他对象- MVC 5 c#

本文关键字:对象 错误 引用 Null MVC 其他 模型 方法 视图 HttpPost | 更新日期: 2023-09-27 18:09:14

我将在讲解过程中解释这个问题。

我这里有这个视图。

视图:

@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包含实际出售的Item以及客户和购买等其他详细信息。

问题是,视图提交后,代码立即转到该模型的无参数构造函数。

// I put in the constructor to initialize those variables in the class.
Item = new ItemModel();

我被告知这是必需的,因为当它获取信息时,它需要一个模型的空实例来填充来自视图的信息。

无论如何,所发生的是,模型(用于出售的物品)以前是空的,在如上所示初始化之后,它现在显示其默认值,但它仍然没有真正由视图返回给控制器。价格为0,名称和描述为空等等。所有其他付款信息,个人信息等都在CheckoutItem中成功发送。

另一个问题是。信用卡信息只是从CheckoutItem的返回变量转移到控制器中的本地变量,但是我们会得到一个Reference Object not Instance(类似于这些行的东西)错误,您可能熟悉这个错误。尽管您可以在控制器中看到,本地信用卡详细信息对象的实例已经在HttpPost方法中初始化了。

任何帮助将感激为什么这些问题发生。我敢肯定是我在某个地方做了一些不太复杂的蠢事。

非常感谢你们,你们之前已经帮助我们解决了这个项目中的一个问题!

HttpPost方法没有从视图中得到正确的模型,也得到Null/引用对象错误与其他对象- MVC 5 c#

在您的视图中,您使用模型的Item属性的唯一地方是这里:

<div class="panel-body">
    Item: @Model.Item.ItemName
</div>

显然,这只是将其名称打印到HTML中。如果不将包含在HTML表单中,则在提交数据时不可能返回任何值。

所以一种可能性是为它们设置隐藏字段:

@Html.HiddenFor(x => x.Item.ItemName)
@Html.HiddenFor(x => x.Item.ItemPrice)
@Html.HiddenFor(x => x.Item.ItemDescription)
...

现在,这些值将在提交表单时发送到服务器。另一种可能性是使用项目id从数据库中获取它们,与在GET操作中使用的方式相同。如果用户不希望修改他们的值,这是推荐的方法。

视图确实需要在与Item Model相关的HTML表单中有隐藏字段,以便视图知道要向控制器提交什么,如@Darin Dimitrov所建议的:

@Html.HiddenFor(x => x.Item.ItemName)
@Html.HiddenFor(x => x.Item.ItemPrice)
@Html.HiddenFor(x => x.Item.ItemDescription)
...

way支付模型/类抛出null错误的另一个问题与它们在对象中有对象这一事实有关。如果你说初始化对象A,它也包含有变量的对象B,那么你需要在A中初始化对象B的实例这样它就不是一个巨大的NULL值,而是一堆其他值。这听起来令人困惑,但它是这样的:

CustomerPayment payment1 = new CustomerPayment();

现在CustomerPayment对象内部包含另一个CreditCardDetails类型的对象CardDetails。这也需要初始化,这样它的变量将是可访问的,整个对象不是空的,像这样:

payment1.CardDetails = new CreditCardDetails();

现在你可以使用它里面的东西并给它们赋值了,例如:

payment1.CardDetails.Number = 1234 1234 1234 1234;

不返回null错误

这是way部分(我们的支付网关)的惰性编码,为我们提供了具有无参数构造函数的类,这些构造函数不会初始化其中封装的其他对象。