0

I am trying to create sub category for categories. User first select the categories from dropdownlist and then type the subcategory name and clicks submit. Even though dropdownlist elements are properly fill the dropdown list. When I click submit button It creates error. How can I solve this? My View:

@model CETAPPSUGG.Models.CategorySubCategoryModel

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

@using (Html.BeginForm())
{
    @Html.HiddenFor(model => model.selectedId, new { id = "3" });


   // @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>SubCatagories</h4>

        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.SubCategory.SubCategoryName, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.SubCategory.SubCategoryName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.SubCategory.SubCategoryName, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
Upper cat:            <div class="col-md-10">
                          @Html.DropDownListFor(Model => Model.Categories, Model.categoryList)


            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

My Controller:

public ActionResult Create()
    {
        var categories = db.Categories.ToList();
        CategorySubCategoryModel deneme = new CategorySubCategoryModel();
        var list = new List<SelectListItem>();
        deneme.Categories = categories;
        foreach (Categories c in categories)
        {
            list.Add(new SelectListItem() { Text = c.CategoryName, Value = c.Id.ToString() });
        }

        deneme.categoryList = list;

        return View(deneme);
    }


   // POST: SubCatagories/Create
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
   // [ValidateAntiForgeryToken]
public ActionResult Create( CategorySubCategoryModel model)
{
    string strDDLValue = model.selectedId;
    SubCatagories newSubCategory = new SubCatagories();
    Categories cat = new Categories();
    cat = db.Categories.Find(Convert.ToInt32(strDDLValue));
    //    cat =  db.Categories.Find(Convert.ToInt32(strDDLValue));

    newSubCategory.SubCategoryName = model.SubCategory.SubCategoryName;
    newSubCategory.UpperCategory = Convert.ToInt32(strDDLValue);
    newSubCategory.Categories = cat;

    db.SubCatagories.Add(newSubCategory);
    db.SaveChanges();

    return View();
}

My Model

namespace CETAPPSUGG.Models
{
    public class CategorySubCategoryModel
    {
        SubCatagories SubCatagories { get; set; }

        public IEnumerable<Categories> Categories { get; set; }
        public IEnumerable<SubCatagories> SubCategories { get; set; }

        public IEnumerable<SelectListItem> categoryList { get; set; }

        public SubCatagories SubCategory { get; set; }

        public string selectedId;

    }
}

It creates error in view

user2394800
  • 11
  • 1
  • 3
  • 1
    Possible duplicate of [What is a NullReferenceException, and how do I fix it?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – mmushtaq May 14 '17 at 17:13

1 Answers1

0

You have a bunch of problems here.

Your primary problem is that you are not passing a model back to the View on post, thus the model is null. So, when you attempt to dereference items from the model in the View, a null reference is generated.

First, you are using selectedId but do not set this anywhere. It doesn't get set by magic. What you probably want is @Html.DropDownListFor(model => model.selectedId, Model.categoryList) (note the lowercase m in model in the first parameter, and uppercase M in the second)

Second, don't use a Model in your lambda in the DropDownListFor, use the lowercase model, because uppercase Model is reserved for the actual Model instance. If you want to reference the Model instance, then do something like DropDownListFor(_ => Model.Foo, Model.Foos). Note that I replaced the Model before the lambda with an underscore or some other value that is not Model. Frankly i'm surprised this even works, but there's probably a scoping rule here that overrides the outer Model. Avoid this because it can cause you confusion down the road.

Third, you are passing an IEnumerable to the DropDownListFor as the selected item variable, this won't work on a number of levels. This needs to be a single string value in most cases (sometimes a numerical one, but always a single more basic type that can have ToString() called on it and get a sensible string since DropDownListFor can't display complex objects).

Fourth, You also need to re-populate your DropDownListFor in the Post action, because the contents of a dropdownlist are not posted back, and thus will be null in the model. This, along with the SubCategory derefences in your view are ultimately what is generating the Null Reference exception.

You also need to pass the model back to your view in the Post, but as stated above, it needs to be re-initialized with the Categories as well as SubCategories.

There are probably more problems here, but fix these and you should be on your way.

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
  • thank you so much. I think my code is garbage. But I will try to fix it. But I changed @Html.DropDownListFor(model => model.selectedId, Model.categoryList) but it gives error to. What change should I do? – user2394800 May 14 '17 at 19:56
  • return RedirectToAction("Index"); I added this. It works now. But I cannot acces selectedId yet. ıt is null. why? – user2394800 May 14 '17 at 20:00
  • @user2394800 - I gave you 4 things you had to change, you changed one of them and said "It still doesn't work!". Try doing everything I said. – Erik Funkenbusch May 14 '17 at 20:28
  • Thank you. I deleted the dropdownlistfor. and add @Html.HiddenFor(model => model.selectedId, new { selectedId = "3" }) this. and it is still null. why?. I cannot spot the problem. – user2394800 May 14 '17 at 20:35
  • @user2394800 - WHY In the world would you do that? I didn't tell you to do that. WTF are you doing? Do WHAT I TOLD YOU to do. – Erik Funkenbusch May 14 '17 at 20:36
  • :D I am so sorry. I am actually noob, trying to spot the problem. I will try to implement the suggestions you made(I am so grateful). I am taking your time. Even @Html.HiddenFor(model => model.selectedId, new { selectedId = "3" });this code do not assign value to my selectedId ? By the way. I will do what did you say. – user2394800 May 14 '17 at 20:41
  • @user2394800 - You're not using HiddenFor correctly. What you wrote does not set the value of the model element, it sets the id of the HTML element. You need to actually set selectedId to 3 for it to show up. – Erik Funkenbusch May 14 '17 at 20:47