Asif Shakir
Asif Shakir

Reputation: 95

Have a null check on Model but still getting Null object reference ASP.NET MVC

controller

public ActionResult EditProduct(int id)
{
     ProductViewModel ViewModel = new ProductViewModel();         
     ViewModel.SingleProduct = DB.Prouducts.Where(x => x.ProductID == id).FirstOrDefault();
     ViewModel.ImageList = DB.ImageGalleries.Where(x => x.ProductIdFk == id).ToList();
     return View(ViewModel);
}


[HttpPost]
public ActionResult EditProduct(Prouduct product, IEnumerable<HttpPostedFileBase> thumb, ImageGallery images)
{
        CategoryDropdown();
        BrandDropdown();
        if (ModelState.IsValid)
        {       
            HttpPostedFileBase Image1 = thumb.FirstOrDefault();        
                product.ProductSlug = slug;
                var userID = Convert.ToInt32(Session["UserID"]);
                product.UserIdFk = userID;
                DB.Entry(product).State = System.Data.Entity.EntityState.Modified;
                DB.SaveChanges();
                int LastInsertedID = product.ProductID;
                foreach (var tmb in thumb)
                {
                    if (tmb != null)
                    {
                        string FileName = tmb.FileName;
                        string Extenstion = Path.GetExtension(FileName);
                        if (Extenstion.ToLower() == ".jpeg" | Extenstion.ToLower() == ".jpg" | Extenstion.ToLower() == ".png" | Extenstion.ToLower() == ".webp")
                        {
                            FileName = FileName + DateTime.Now.ToString("yyyyMMddHHmmssfff") + Extenstion;
                            string ImageSavePath = Server.MapPath("/Content/Assets/Photos/");
                            tmb.SaveAs(Path.Combine(ImageSavePath + FileName));
                            string ThumbSavePath = Server.MapPath("/Content/Assets/Photos/Thumbs/");
                            ThumbGenration.ResizeStream(522, tmb.InputStream, Path.Combine(ThumbSavePath + FileName));
                            images.ImageName = FileName;
                            images.ImageThumb = FileName;
                            images.ProductIdFk = LastInsertedID;
                            //var userID = Convert.ToInt32(Session["UserID"]);
                            images.UserIdFk = userID;
                            DB.ImageGalleries.Add(images);
                            DB.SaveChanges();
                            TempData["Success"] = "Data Added Successfully!";
                        }
                    }
                }
        }
       return View();
    }

View

@model  RentalServices.Models.ProductViewModel


 @using (Html.BeginForm("EditProduct", "Product", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.SingleProduct.ProductID);
<div class="add-item-wrapper">
    <h4>Listing Details</h4>
    <hr class="noPadMar" />
    <div class="add-item">
        <div class="row">
            <div class="col-sm-10 col-sm-offset-1">
                <div class="col-md-12 col-sm-12 form-group">
                    @*<label class="col-sm-3 col-md-3 control-label">Title</label>*@
                    @Html.LabelFor(model => model.SingleProduct.Title, htmlAttributes: new { @class = "col-sm-3 col-md-3 control-label" })
                    <div class="col-sm-9">
                        @*<input type="text" class="form-control" placeholder="TITLE" />*@
                        @Html.EditorFor(model => model.SingleProduct.Title, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.SingleProduct.Title, "", new { @class = "text-danger" })
                    </div>
                </div>
                <div class="col-md-12 col-sm-12 form-group">
                    @Html.LabelFor(model => model.SingleProduct.Price, htmlAttributes: new { @class = "col-sm-3 col-md-3 control-label" })
                    <div class="col-sm-9">
                        @Html.EditorFor(model => model.SingleProduct.Price, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.SingleProduct.Price, "", new { @class = "text-danger" })
                    </div>
                </div>
                <div class="col-md-12 col-sm-12 form-group">
                    @Html.Label("CATEGORY", htmlAttributes: new { @class = "col-sm-3 col-md-3 control-label" })
                    <div class="col-sm-9">
                        @Html.DropDownListFor(model => model.SingleProduct.CategoryIdFk, ViewBag.CategoryDropdown as SelectList, "CHOOSE CATEGORY", new { @class = "form-control", id = "CategoryID" })
                        @Html.ValidationMessageFor(model => model.SingleProduct.CategoryIdFk, "", new { @class = "text-danger" })
                    </div>
                </div>
                <div id="hide">
                    <div class="col-md-12 col-sm-12 form-group">
                        @Html.Label("BRAND", htmlAttributes: new { @class = "col-sm-3 col-md-3 control-label" })
                        <div class="col-sm-9">
                            @Html.DropDownListFor(model => model.SingleProduct.BrandIdFk, ViewBag.BrandDropdown as SelectList, "CHOOSE BRAND", new { @class = "form-control", id = "BrandID" })
                            @Html.ValidationMessageFor(model => model.SingleProduct.BrandIdFk, "", new { @class = "text-danger" })
                        </div>
                    </div>


                    <div class="col-md-12 col-sm-12 form-group">
                        @Html.LabelFor(model => model.SingleProduct.Ram, htmlAttributes: new { @class = "col-sm-3 col-md-3 control-label" })
                        <div class="col-sm-9">
                            @Html.EditorFor(model => model.SingleProduct.Ram, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.SingleProduct.Ram, "", new { @class = "text-danger" })
                        </div>
                    </div>
                    <div class="col-md-12 col-sm-12 form-group">
                        @Html.LabelFor(model => model.SingleProduct.Processor, htmlAttributes: new { @class = "col-sm-3 col-md-3 control-label" })
                        <div class="col-sm-9">
                            @Html.EditorFor(model => model.SingleProduct.Processor, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.SingleProduct.Processor, "", new { @class = "text-danger" })
                        </div>
                    </div>
                </div>
                <div class="col-md-12 col-sm-12 form-group">
                    @Html.Label("CONDITION", htmlAttributes: new { @class = "col-sm-3 col-md-3 control-label" })
                    <div class="col-sm-9">
                        @Html.DropDownListFor(model => model.SingleProduct.Conditon, selectList, "CHOOSE CONDITION", new { @class = "form-control" })
                        @Html.ValidationMessageFor(model => model.SingleProduct.Conditon, "", new { @class = "text-danger" })
                    </div>
                </div>
                <div class="col-md-12 col-sm-12 form-group">
                    @Html.LabelFor(model => model.SingleProduct.Location, htmlAttributes: new { @class = "col-sm-3 col-md-3 control-label" })
                    <div class="col-sm-9">
                        @Html.EditorFor(model => model.SingleProduct.Location, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.SingleProduct.Location, "", new { @class = "text-danger" })
                    </div>
                </div>
                <div class="col-md-12 col-sm-12 form-group">
                    @Html.LabelFor(model => model.SingleProduct.Description, htmlAttributes: new { @class = "col-sm-3 col-md-3 control-label" })
                    <div class="col-sm-9">
                        @Html.TextAreaFor(model => model.SingleProduct.Description, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.SingleProduct.Description, "", new { @class = "text-danger" })
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<div class="image-gallery-wrapper">
    <div class="img-gallery">
        @if (Model.ImageList.Any())
        {
            foreach (var item in Model.ImageList)
            {
                <div class="img-wrapper">
                    <p>Image 1</p>
                    <div class="img-box">
                        <input type="file" name="thumb" value="" class="file-style" onchange="readURL(this)" ; />
                        <img src="/Content/Assets/Photos/Thumbs/@item.ImageName" alt="your image" id="imgName" value="@item.ImageName" />
                        <button id="RemoveImage">Remove Image</button>
                    </div>
                </div>

            }
        }

    </div>        
</div>
<div class="text-center">
    <button type="submit" class="roundSubmitBtn" style="background:#7048f0 !important;font-size:14px !important; margin-top:40px;">SUMBIT <i class="fa fa-arrow-right"></i></button>
</div>
}

As i added my code i am getting null exception error.but i have a check of null or not so why i am getting this null object reference error. and i have also tried Count() and !=null in IF statement.i am getting erro while i submit form and error is null exception error so tell me where i am wrong

Upvotes: 0

Views: 201

Answers (1)

Tetsuya Yamamoto
Tetsuya Yamamoto

Reputation: 24957

By inspecting POST action method provided in question, the problem seem coming from return View() statement which returns same view page as in GET action method but without returning viewmodel class instance, which causing ProductViewModel.ImageList contains null value.

The brief code below shows the problem:

[HttpPost]
public ActionResult EditProduct(Prouduct product, IEnumerable<HttpPostedFileBase> thumb, ImageGallery images)
{
    CategoryDropdown();
    BrandDropdown();
    if (ModelState.IsValid)
    {       
       // image processing and saving to DB
    }

    // the view returned without viewmodel
    // this will trigger NullReferenceException because ProductViewModel.ImageList is not reassigned yet
    return View();
}

Therefore, you should reassign ProductViewModel.ImageList property after saving posted data into database, and return the same view together with new ProductViewModel instance (or redirect to another action if necessary by following PRG pattern with RedirectToAction):

[HttpPost]
public ActionResult EditProduct(Prouduct product, IEnumerable<HttpPostedFileBase> thumb, ImageGallery images)
{
    CategoryDropdown();
    BrandDropdown();
    if (ModelState.IsValid)
    {       
       // image processing and saving to DB
    }

    // create viewmodel instance
    var ViewModel = new ProductViewModel();         

    ViewModel.ImageList = ...; // reassign ImageList property here
    return View(ViewModel);
}

Upvotes: 1

Related Questions