-1

Error:

The parameters dictionary contains a null entry for parameter 'categoryId' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult UpdateCategory(Int32)' in 'OnlineStore.Controllers.AdminController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter. Parameter name: parameters.

This is the code:

@model OnlineStore.Models.CategoryDetail
@{
    ViewBag.Title = "UpdateCategory";
    Layout = "~/Views/Shared/_AdminLayout.cshtml";
}




<div class="container-fluid">
    <!-- Breadcrumbs-->

    <ol class="breadcrumb">
        <li class="breadcrumb-item">
            <a href="#">Dashboard</a>
        </li>
        <li class="breadcrumb-item ">Categories</li>
        <li class="breadcrumb-item active">Add New Category</li>


    </ol>
    <!-- DataTables Example -->
    <div class="card mb-3">
        <div class="card-header">
            <i class="fas fa-table"></i>
            Add New Category

        </div>
        <div class="card-body">
            @using (Html.BeginForm("UpdateCategory", "Admin", FormMethod.Post, new { enctype = "multipart/form-data" }))
            {
                @Html.HiddenFor(m => m.CategoryId)

                <div class="form-group">
                    <label class="control-label">Category Name</label>

                    @Html.TextBoxFor(m => m.CategoryName, new { @class = "form-control", placeholder = "Enter category Name", required = "required", autofocus = "autofocus" })
                    @Html.ValidationMessageFor(m => m.CategoryName, "", new { @class = "text-danger" })
                </div>

                <a onclick="window.history.back();" class="btn btn-danger">Cancel</a>
                <input type="submit" class="btn btn-primary" value="Save" />
            }
        </div>
    </div>
</div>

public ActionResult UpdateCategory(int categoryId)
        {
            CategoryDetail cd;
            if (categoryId != null)
            {
                cd = JsonConvert.DeserializeObject<CategoryDetail>(JsonConvert.SerializeObject(_unitOfWork.GetRepositoryInstance<Tbl_Category>().GetFirstorDefault(categoryId)));
            }
            else
            {
                cd = new CategoryDetail();
            }
            return View("UpdateCategory", cd);

        }
halfer
  • 19,824
  • 17
  • 99
  • 186
Adrian
  • 1

1 Answers1

0

Html.HiddenFor assumes that the submit action parameter is a viewmodel object - so the name it generates for the hidden input is crafted so that the MVC model binder recognises it as the property of a CategoryDetail. You don't have this however - you're passing a bare integer back to the action method instead. This is fine, but the two approaches don't match up.

You can fix this in either of two ways:

  • change the action method to take a CategoryDetail parameter. This will be a new instance of the class with only the values populated by the form post body.
  • use Html.Hidden instead, which does not try to guess the name of the generated input control, and pass a parameter object new { @name = "categoryId" } - according to this answer HiddenFor is meant to be helpful and doesn't allow this level of flexibility
Tom W
  • 5,108
  • 4
  • 30
  • 52