How to resolve " System.ArgumentException: Value cannot be null or empty. Parameter name: contentPath" this error? - asp.net-mvc

The following is my updateproduct.cshtml file where i am getting an error.
#model ShopperDB.Context.Product
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h2 class="admin-title text-center">Edit Product</h2>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.ProductID)
<div class="form-group">
#Html.LabelFor(model => model.ProductName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-6">
#Html.EditorFor(model => model.ProductName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ProductName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ProductImage, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-6">
<img src="#Url.Content(Model.ProductImage)" alt="IMAGES" height="300" ; width="300" />
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Description, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-6">
#Html.EditorFor(model => model.Description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Description, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Price, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-6">
#Html.EditorFor(model => model.Price, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Price, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CategoryID, "CategoryName", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-6">
#Html.DropDownList("CategoryID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.CategoryID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
</div>
</div>
</div>
</div>
}
The following is my update product method from product controller.
//Update the product
[HttpGet]
[Route("product/update/{id}")]
[CustomAuthorize("admin")]
public ActionResult UpdateTheProduct(int? id)
{
if (Session["UserName"].ToString() != null)
{
if (Session["UserName"].ToString() == "admin")
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Product product = db.Products.Find(id);
if (product == null)
{
return HttpNotFound();
}
ViewBag.CategoryID = new SelectList(db.ProductCategories, "CategoryID", "CategoryName");
return View(product);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
return RedirectToAction("Index", "Home");
}
}
[HttpPost]
[ValidateAntiForgeryToken]
[Route("product/update/{id}")]
[CustomAuthorize("admin")]
public ActionResult UpdateTheProduct([Bind(Include = "ProductID,ProductName,ProductImage,Description,Price,CategoryID")] Product product)
{
if (ModelState.IsValid)
{
if (db.Products.Any(ac => ac.ProductName.Equals(product.ProductName)))
{
TempData["fail"] = "Category already Added";
}
else
{
TempData["notice"] = "Successfully Added";
db.Entry(product).State = EntityState.Modified;
db.SaveChanges();
}
return RedirectToAction("ListOfProducts");
}
return View(product);
}
while i am updating the product it is showing me System.ArgumentException: Value cannot be null or empty.Parameter name: contentPath this error on storing ProductImage point.
So please kindly help me to resolve this error.

This part of code in your view potentially throwing contentPath exception:
<img src="#Url.Content(Model.ProductImage)" alt="IMAGES" height="300" ; width="300" />
If Model.ProductImage value is null or empty instead of containing a relative path string when passed to view, it will throw contentPath exception since Url.Content method cannot have null or empty argument.
To solve content URL issue, put if-condition check against null or empty value on ProductImage property in UpdateTheProduct (either GET or POST action method, or both of them) and set its default value using relative path:
if (String.IsNullOrEmpty(Model.ProductImage))
{
Model.ProductImage = "~/path/imagefile";
}
// some code
return View(product);
Related issues:
Value cannot be null or empty. Parameter name: contentPath
"Value cannot be null or empty. Parameter name: contentPath" on a most unexpected line on postback when ModelState has errors

Related

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
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);
}

Model is invalid despite values are correct, strange behaviour [duplicate]

I cannot figure out why my view only passes back a NULL for a model to my controller.
This is for an Edit Post method. I checked other controllers with Edit Post methods that are structured the same way as this one and they work fine. It seems to be just this view and controller.
Here is my view:
#model Non_P21_Quote_System_v1._0.Models.gl_code
#{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Edit</h2>
#if (TempData["Message"] != null)
{
<div style="color:green">
#TempData["Message"]
</div><br />
}
#if (ViewBag.error != null)
{
<div style="color:red">
<h3>#ViewBag.error</h3>
</div><br />
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>gl_code</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.ID)
<div class="form-group">
#Html.LabelFor(model => model.GL_code, "GL Code", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.GL_code, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.GL_code, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.GL_description, "Gl Description", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.GL_description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.GL_description, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.expense_type_ID, "Expense", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("expense_type_ID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.expense_type_ID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.eag, "Employee Account Group", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("eag", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.eag, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "gl_Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Here is my controller method:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "ID,GL_code,GL_description,expense_type_ID,eag")] gl_code gl_code)
{
if (ModelState.IsValid)
{
db.Entry(gl_code).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("gl_Index");
}
ViewBag.eag = new SelectList(db.employee_account_group, "ID", "eag_name");
ViewBag.expense_type_ID = new SelectList(db.expense_type, "ID", "type", gl_code.expense_type_ID);
return View(gl_code);
}
When I debug it, I see the model being passed in is of value NULL. I am seeing this on the controller side at the the parameters part of the Edit method.
Its null because your model contains a property named gl_code and you have also named the parameter for your model gl_code in the POST method.
Change the name of one or the other and the model will bind correctly.
What is happening internally is that the form submits a name/value pair for each successful form control, in your case gl_code=someValue. The DefaultModelBinder first initializes a new instance of your model. It then reads the form values and finds a match for the property in your model and sets it to someValue. But it also finds a match in the method parameters and tries set the value of the parameter to someValue, which fails (because you cannot do gl_code gl_code = "someValue";) and the model becomes null.
It appears you have a property on your view model called gl_code. In your controller, you also refer to the view model as gl_code.
Try changing this.
public async Task<ActionResult> Edit(gl_code gl_code)
To
public async Task<ActionResult> Edit(gl_code model)

Binding dropdownlist with database table and get selected item n MVC

I am new to asp.net mvc.
I have a employee registration view, where i have a dropdown-list for for department, I want to bind the dropdown-list with a database table tblDepartment and i have did it. But I don't know how to get the select item of the list on post-back.
Employee Controller
[HttpGet]
public ActionResult AddEmployee()
{
ViewBag.Departments = new SelectList(_department.GetAll(), "id", "name");
return View(_employee.Get());
}
[HttpPost]
public ActionResult AddEmployee(FormCollection data)
{
var emp = _employee.Get();
emp.name = data["name"];
emp.age = Convert.ToInt32(data["age"]);
emp.dept_id = Convert.ToInt32(data["dept_id"]); // return dept_id 0 always.
emp.city = data["city"];
_employee.Insert(emp);
return RedirectToAction("Index");
}
View
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.name, "Name", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.age, "Age", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.age, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.age, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.dept_id, "Department", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("Departments", "Select Department")
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.city, "City", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.city, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.city, "", new { #class = "text-danger" })
</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>
}
You are defining your dropdownlist with name DropDownLists i.e. #Html.DropDownList("Departments" which will be the name of the drop-down list so it will be rendered like:
<select name="Departments">
</select>
and in form post the values are posted in key value pair and the key is the name of the input element.
But in post request you are finding the posted value in dept_id, you need to read from correct key in FormCollection which would be:
emp.dept_id = Convert.ToInt32(data["Departments"]);
Side Note:
You should be using strongly typed helpers to post values directly to model and let the model binder do the magic for you, instead of populating the model manually.
For that your helper method would be DropDownListFor :
#Html.DropDownListFor(x=>x.dept_id ,ViewBag.Departments as SelectList, "Select Department")
and in action method set the parameter to be mode object:
[HttpPost]
public ActionResult AddEmployee(Employee employee)
{
If(ModelState.IsValid)
{
_employee.Insert(employee);
return RedirectToAction("Index");
}
else
{
return View(employee);
}
}

defaulting value in MVC create view before http post

Hi I am trying to default a date with 'DateTime.Now' in a create view. And setting an 'Active' field to 'true'
The following code does that in the the following action in the controller:
// POST: RequestTypes/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 async Task<ActionResult> Create([Bind(Include = "Id,RequestTypeDescription,LastUpdated,Active,Team")] RequestType requestType)
{
if (ModelState.IsValid)
{
db.RequestTypes.Add(requestType);
requestType.LastUpdated = System.DateTime.Now;
requestType.Active = true;
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
ViewBag.Team = new SelectList(db.Teams, "Id", "TeamDescription", requestType.Team);
return View(requestType);
}
That is the httppost code which defaults when the save is made.
What I want to do is to default those fields so that they show when the create view first gets launched - with the following code in the following action:
// GET: RequestTypes/Create
public ActionResult Create()
{
ViewBag.Team = new SelectList(db.Teams, "Id", "TeamDescription");
ViewBag.LastUpdated = System.DateTime.Now;
return View();
}
My Create View code is the standard created by MVC scaffolding:
#model ManageHR5.Models.RequestType
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>RequestType</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.RequestTypeDescription, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.RequestTypeDescription, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.RequestTypeDescription, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LastUpdated, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.LastUpdated, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LastUpdated, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Active, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.Active)
#Html.ValidationMessageFor(model => model.Active, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Team, "Team", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("Team", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Team, "", new { #class = "text-danger" })
</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>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")}
When I run the app, and launch the create page, the defaults don't show up when the create page is launched.
What am I not understanding?
(A newbie to MVC :( )
You set them in the model on the Get for display purposes
// GET: RequestTypes/Create
public ActionResult Create() {
ViewBag.Team = new SelectList(db.Teams, "Id", "TeamDescription");
var model = new RequestType();
model.LastUpdated = System.DateTime.Now;
model.Active = true;
return View(model);
}
But like indicated in the provided comment
You set them immediately before you save the object in the POST method

After i modify my Model : Values of my form are = NULL [duplicate]

I cannot figure out why my view only passes back a NULL for a model to my controller.
This is for an Edit Post method. I checked other controllers with Edit Post methods that are structured the same way as this one and they work fine. It seems to be just this view and controller.
Here is my view:
#model Non_P21_Quote_System_v1._0.Models.gl_code
#{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Edit</h2>
#if (TempData["Message"] != null)
{
<div style="color:green">
#TempData["Message"]
</div><br />
}
#if (ViewBag.error != null)
{
<div style="color:red">
<h3>#ViewBag.error</h3>
</div><br />
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>gl_code</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.ID)
<div class="form-group">
#Html.LabelFor(model => model.GL_code, "GL Code", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.GL_code, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.GL_code, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.GL_description, "Gl Description", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.GL_description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.GL_description, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.expense_type_ID, "Expense", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("expense_type_ID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.expense_type_ID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.eag, "Employee Account Group", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("eag", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.eag, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "gl_Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Here is my controller method:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "ID,GL_code,GL_description,expense_type_ID,eag")] gl_code gl_code)
{
if (ModelState.IsValid)
{
db.Entry(gl_code).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("gl_Index");
}
ViewBag.eag = new SelectList(db.employee_account_group, "ID", "eag_name");
ViewBag.expense_type_ID = new SelectList(db.expense_type, "ID", "type", gl_code.expense_type_ID);
return View(gl_code);
}
When I debug it, I see the model being passed in is of value NULL. I am seeing this on the controller side at the the parameters part of the Edit method.
Its null because your model contains a property named gl_code and you have also named the parameter for your model gl_code in the POST method.
Change the name of one or the other and the model will bind correctly.
What is happening internally is that the form submits a name/value pair for each successful form control, in your case gl_code=someValue. The DefaultModelBinder first initializes a new instance of your model. It then reads the form values and finds a match for the property in your model and sets it to someValue. But it also finds a match in the method parameters and tries set the value of the parameter to someValue, which fails (because you cannot do gl_code gl_code = "someValue";) and the model becomes null.
It appears you have a property on your view model called gl_code. In your controller, you also refer to the view model as gl_code.
Try changing this.
public async Task<ActionResult> Edit(gl_code gl_code)
To
public async Task<ActionResult> Edit(gl_code model)

Resources