简体   繁体   中英

mvc model null reference

In my web application something strange is going on and I can not find a cause. Please help me or provide me some idea how to solve this challenge. The same code works in some cases for the other I get null reference Exception. In controller I get a model for a specific category from DB. Then, in view I list all products from this category. When I select some products from the list and press button 'To Shopping Cart', sometimes model is passed/transferred to the controller correctly and sometimes Products in model are null.

My controller actions:

    [HttpGet]
    [PacCheckPermissionAttribute(PacPermissionRecordEnum.perm_pubmatorder)]
    public ActionResult PacCategoryDetails(int categoryId)
    {
        Category category = _categoryService.GetCategoryById(categoryId);
        if(category == null || category.Deleted || !category.Published)
            return RedirectToRoute("HomePage");


        CategoryModel model = prepareCategoryModel(category, false);
        return View(model);
    }

    [HttpPost]
    [PacCheckPermissionAttribute(PacPermissionRecordEnum.perm_pubmatorder)]
    public ActionResult PacCategoryDetails(CategoryModel model)
    {
        Category category = _categoryService.GetCategoryById(model.Id);
        if (category == null || category.Deleted || !category.Published)
            return RedirectToRoute("HomePage");

        //Add the selected Products to ShoppingCart
        for (int i = 0; i < model.Products.Count; i++)
        ...

model.Products is sometimes null and sometimes correct - don't know really why??? My View:

    @model CategoryModel
    @using Nop.Web.Models.Catalog;
    @using Nop.Core.Domain.Orders;
    @using Nop.Web.Framework;
    @using Nop.Web.Models.ShoppingCart;
    @using PacControls;
    @using Telerik.Web.Mvc.UI;
    @{
        Html.AppendScriptParts(@Url.Content("~/Administration/Scripts/jquery.validate.unobtrusive.min.js"));
        Html.AppendScriptParts(@Url.Content("~/Administration/Scripts/jquery.validate.min.js"));
        Html.AppendScriptParts(@Url.Content("~/Administration/Scripts/jquery.unobtrusive-ajax.min.js"));
        Layout = "~/Views/Shared/_PacLoggedIn.cshtml";
    }
    @section SideBar
    {
        @Html.Action("PacCategoryNavigation", "Catalog", new { currentCategoryId = Model.Id})
    }
    @using (Html.BeginForm())
    {
        <div class="productdetails-page">
            <div class="body">
                <div class="info-row">
                    <div class="productlist-content">
                        <div class="info-row">
                            <div class="box border-r box-s info-row category-details">
                                <!-- <div class="f-l" style="width: 320px;">@Html.Partial("_ProductDetailsPictures", Model)</div> -->
                                <div class="f-l" style="width: 360px;"><h1>@Html.DisplayTextFor(x => Model.Name)</h1>
                                                 @Html.Raw(Model.Description)
                                                 @Html.HiddenFor(x => Model.Id)
                                </div>
                                <div class="f-c"></div>
                            </div>
                            <div class="f-c"></div>
                        </div>
                        <div class="f-c"></div> 
                        @if (Model.Products.Count > 0)
                        {
                            <div class="titelbox border-top-r-l full-row darkgrey-background">
                                <div class="page-title">
                                    <h3>@T("Pac.PromotionMaterial")</h3>
                                </div>
                            </div>
                            <div class="box border-bottom-r-l info-row">
                                <div class="osc-data">
                                    <div class="osc-table">
                                        <div class="mm-items">
                                        @for (int i = 0; i < Model.Products.Count; i++)
                                        {
                                            if (!Model.Products[i].IsDownload)
                                            {
                                                <div class="mm-row" id="@(i)">
                                                    @Html.HiddenFor(x => Model.Products[i].Id)
                                                    <div class="mm-col quanity-col">
                                                        <div>
                                                            @Html.EditorFor(x => Model.Products[i].Quantity)
                                                            @Html.ValidationMessageFor(x => Model.Products[i].Quantity)
                                                        </div>     
                                                    </div>
                                                    <div class="mm-col name-col">
                                                        <div id="name_@(i)">
                                                            @Html.DisplayTextFor(x => Model.Products[i].Name)
                                                        </div>
                                                    </div>
                                                    <div class="mm-col price-col">
                                                        <div>
                                                            <div id="price_@(i)" class="price-col">@Html.DisplayTextFor(x => @Model.Products[i].ProductPrice.Price)</div> 
                                                            <input type="hidden" id="pricevalue_@(i)" value="@(Model.Products[i].ProductPrice.PriceValue)"/>
                                                        </div>    
                                                    </div>
                                                    <div class="f-c"></div>
                                                </div>
                                            }
                                        }
                                        </div>
                                    </div>
                                </div>
                            </div>
                        }
                            @if (Model.Products.Count > 0)
                            {
                            <div class="titelbox border-top-r-l full-row darkgrey-background">
                                <div class="page-title">
                                    <h3>@T("Pac.Download")</h3>
                                </div>
                            </div>
                            <div class="box border-bottom-r-l info-row">
                                <div class="osc-data">
                                    <div class="osc-table">
                                        <div class="mm-items">
                                        @for (int i = 0; i < Model.Products.Count; i++)
                                        {
                                            if (Model.Products[i].IsDownload)
                                            {
                                                <div class="mm-row" id="@(i)">
                                                    <div class="mm-col downloadname-col">
                                                        <div>
                                                            @Html.DisplayTextFor(x => Model.Products[i].Name)
                                                        </div>
                                                    </div>
                                                    <div class="mm-col downloadbutton-col">
                                                        @if (Model.Products[i].IsDownload)
                                                        {
                                                            @Html.SmallButton(T("Pac.Button.Download").Text, ButtonStyle.Default, "location.href = '" +Url.RouteUrl("GetProductDownload", new { productvariantid = Model.Products[i].ProductVariantId }) + "';return false;" , new Dictionary<string, object>() { { "class", "smallbuttoncart" } })
                                                        }
                                                    </div>
                                                    <div class="f-c"></div>
                                                </div>
                                            }
                                        }
                                        </div>
                                    </div>
                                </div>
                            </div>
                            }
                            <div class="titelbox border-top-r-l full-row darkgrey-background">
                                <div class="page-title darkgrey-background">
                                    <h3>@T("Pac.Summary")</h3>
                                </div>
                            </div>
                            <div class="box border-bottom-r-l info-row">
                                <div class="osc-data">
                                    <div class="osc-table">
                                        <div class="mm-items" id="summarytable">
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="f-c"></div>  
                        <div class="f-r full-row right">
                        @Html.SubmitButton(T("Pac.Button.ToShoppingCart").Text, ButtonStyle.Lightgrey)
                        </div>
                        <div class="f-c "></div>
                </div>
            </div>
        </div>
    }
<script type="text/javascript" language="javascript">

    var summaryrow = "<div class=\"mm-row mm-summaryrow\"><div class=\"mm-col summaryquantity-col\" id=\"summaryrow\"></div><div class=\"mm-col summaryname-col\">@T("Pac.Price")</div><div class=\"mm-col summaryprice-col\">#price#</div><div class=\"f-c\"></div></div>";
    var elementrow = "<div class=\"mm-row\" id=\"summaryrow_\"><div class=\"mm-col summaryquantity-col\" id=\"summaryquanity_\">#quantity#</div><div class=\"mm-col summaryname-col\" id=\"summaryname_\">#name#</div><div class=\"mm-col summaryprice-col\" id=\"summaryprice_\">#price#</div><div class=\"f-c\"></div></div>";

    function calculateSummary() {
        var sum = 0.00;
        var position = 0;

        $('#summarytable').empty();

        $('input[id$="Quantity"]').each(
            function () {

                //summ price
                var id = this.id.substring(this.id.indexOf("[")+1, this.id.indexOf("]"));
                var price = $('#pricevalue_' + id)[0].value.replace(",",".");
                var quantity = this.value;
                var val = 0;
                if(!isNaN(quantity) && !isNaN(price) && quantity > 0)
                {
                    val = parseFloat(quantity) * parseFloat(price);
                    sum = sum + val;

                    //Create new Row
                    var newrow = elementrow;
                    newrow = newrow.replace("#quantity#", this.value);
                    newrow = newrow.replace("#name#", $('#name_' + id)[0].innerHTML);
                    newrow = newrow.replace("#price#", val.toFixed(2).replace(".",",") + " (EUR)");
                    newrow = newrow.replace("summaryrow_", "summaryrow_" + id);
                    newrow = newrow.replace("summaryquanity_", "summaryquanity_" + id);
                    newrow = newrow.replace("summaryname_", "summaryname_" + id);
                    newrow = newrow.replace("summaryprice_", "summaryprice_" + id);

                    //add row to summarytable
                    $('#summarytable').append(newrow);
                }
            }
            );

        var newsummaryrow = summaryrow;
        newsummaryrow = newsummaryrow.replace("#price#", sum.toFixed(2).replace(".",",") + " (EUR)");
        $('#summarytable').append(newsummaryrow);
    }

    function addOnUpdateFunctions()
    {
        $('input[id$="Quantity"]').each(
            function () {
                this.setAttribute("onchange", "calculateSummary();");
                });
        $("a[class^='t-link t-icon t-arrow-']").each(
            function () {
                this.setAttribute("onclick", "calculateSummary();");
                });
    }

    $(document).ready(calculateSummary());
    $(document).ready(addOnUpdateFunctions());
</script>

@(Html.Telerik().StyleSheetRegistrar()
        .DefaultGroup(group => group
            .Add("telerik.common.min.css")
            .Add("telerik.vista.min.css")
            .Add("telerik.rtl.min.css")
            ))
@(Html.Telerik().ScriptRegistrar()
        .jQuery(false)
        .jQueryValidation(false)
        )

Any idea what is happening? Thanx!

You have two conditions that keep products from getting listed in the <form> :

if (Model.Products.Count > 0)

and:

if (Model.Products[i].IsDownload)

so, if there are no products in the category or there are no downloadable products, then the Products will be null when posted. This is expected behavior. Just check for null and do what you need to do. In this case I'd say you probably just ignore it because there are no products to add to the shopping cart and the user just likely clicked it in error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM