Multiple models for one view not working - asp.net-mvc

I have a Customer model and a Project model that I made into a Partial View.
I basically have a class and the two models that I'm using for the View are inside the main class.
The DataAnnotations are working just fine for both models.
When I hit the submit button and post back, the ViewModel that I'm using is null for the CustomerDTO & ProjectDTO models. In other words, the variable customerProject is null for both classes.
I think it must have something to do with the model binding.
I would appreciate very much if someone can point out what I'm doing wrong.
Note that if I just use one class without wrapping the sub-classes inside the superclass, the "customer" object is populated.
public ActionResult CreateCust(CustomerDTO customer)
This one class is defined as follows:
using Models.Models;
namespace Models.ViewModels.Customers
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public class CustomerDTO
{
[Key]
[ScaffoldColumn(true)]
[Display(Name = "ID")]
public short CustomerID { get; set; }
[Required]
[StringLength(50)]
public string UserName { get; set; }
[Required]
[StringLength(50)]
[EmailAddress]
public string Email { get; set; }
[StringLength(50)]
public string Company { get; set; }
[StringLength(50)]
public string FirstName { get; set; }
[StringLength(50)]
public string LastName { get; set; }
[StringLength(50)]
public string Address1 { get; set; }
[StringLength(50)]
public string Address2 { get; set; }
[StringLength(50)]
public string City { get; set; }
[StringLength(2)]
public string State { get; set; }
[StringLength(10)]
[DataType(DataType.PostalCode)]
[RegularExpression(#"^\d{5}(-\d{4})?$")]
public string Zip { get; set; }
[StringLength(12)]
[DataType(DataType.PhoneNumber)]
[RegularExpression(#"^\s*([\(]?)\[?\s*\d{3}\s*\]?[\)]?\s*[\-]?[\.]?\s*\d{3}\s*[\-]?[\.]?\s*\d{4}$")]
public string HomePhone { get; set; }
[StringLength(12)]
[DataType(DataType.PhoneNumber)]
[RegularExpression(#"^\s*([\(]?)\[?\s*\d{3}\s*\]?[\)]?\s*[\-]?[\.]?\s*\d{3}\s*[\-]?[\.]?\s*\d{4}$")]
public string CellPhone { get; set; }
[StringLength(100)]
[DataType(DataType.Url)]
public string Website { get; set; }
[StringLength(50)]
[DataType(DataType.Url)]
public string IMAddress { get; set; }
[DataType(DataType.DateTime)]
[Display(Name = "Created")]
public DateTime CreatedDate { get; set; }
[DataType(DataType.DateTime)]
[Display(Name = "Updated")]
public DateTime? UpdatedDate { get; set; }
public virtual ICollection<Project> Projects { get; set; }
}
}
Here is my model (Please use your favorite viewer to view the image to enlarge it).
My Main View is defined as follows:
#model Models.ViewModels.Customers.CustomerDTO
#{
ViewBag.Title = "Create Customer & Project";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Create</h2>
#using (Html.BeginForm("CreateCustProj", "Home", FormMethod.Post, new { #id = "frm1", #class = "form-horizontal" }))
{
<div class="body-content">
<h4>Customer/Project</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<fieldset>
<legend>Customer</legend>
<div class="form-group">
<div class="col-lg-offset-1 col-md-offset-1 col-sm-offset-1 col-xs-offset-1 col-lg-11 col-md-11 col-sm-11 col-xs-11">
#Html.EditorFor(model => model.UserName, new { htmlAttributes = new { #class = "form-control", #placeholder = "UserName" } })
#Html.ValidationMessageFor(model => model.UserName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-1 col-md-offset-1 col-sm-offset-1 col-xs-offset-1 col-lg-11 col-md-11 col-sm-11 col-xs-11">
#Html.EditorFor(model => model.Email, new { htmlAttributes = new { #class = "form-control", #placeholder = "Email" } })
#Html.ValidationMessageFor(model => model.Email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-1 col-md-offset-1 col-sm-offset-1 col-xs-offset-1 col-lg-11 col-md-11 col-sm-11 col-xs-11">
#Html.EditorFor(model => model.Company, new { htmlAttributes = new { #class = "form-control", #placeholder = "Company" } })
#Html.ValidationMessageFor(model => model.Company, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-1 col-md-offset-1 col-sm-offset-1 col-xs-offset-1 col-lg-5 col-md-5 col-sm-5 col-xs-5">
#Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { #class = "form-control", #placeholder = "First Name" } })
#Html.ValidationMessageFor(model => model.FirstName, "", new { #class = "text-danger" })
</div>
<div class="col-lg-5 col-md-5 col-sm-5 col-xs-5">
#Html.EditorFor(model => model.LastName, new { htmlAttributes = new { #class = "form-control", #placeholder = "Last Name" } })
#Html.ValidationMessageFor(model => model.LastName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-1 col-md-offset-1 col-sm-offset-1 col-xs-offset-1 col-lg-11 col-md-11 col-sm-11 col-xs-11">
#Html.EditorFor(model => model.Address1, new { htmlAttributes = new { #class = "form-control", #placeholder = "Address1" } })
#Html.ValidationMessageFor(model => model.Address1, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-1 col-md-offset-1 col-sm-offset-1 col-xs-offset-1 col-lg-11 col-md-11 col-sm-11 col-xs-11">
#Html.EditorFor(model => model.Address2, new { htmlAttributes = new { #class = "form-control", #placeholder = "Address2" } })
#Html.ValidationMessageFor(model => model.Address2, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-1 col-md-offset-1 col-sm-offset-1 col-xs-offset-1 col-lg-6 col-md-6 col-sm-6 col-xs-6">
#Html.EditorFor(model => model.City, new { htmlAttributes = new { #class = "form-control", #placeholder = "City" } })
#Html.ValidationMessageFor(model => model.City, "", new { #class = "text-danger" })
</div>
<div class="col-md-3 col-sm-3 col-xs-3">
#Html.EditorFor(model => model.State, new { htmlAttributes = new { #class = "form-control", #placeholder = "State" } })
#Html.ValidationMessageFor(model => model.State, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-1 col-md-offset-1 col-sm-offset-1 col-xs-offset-1 col-lg-3 col-md-3 col-sm-3 col-xs-3">
#Html.EditorFor(model => model.Zip, new { htmlAttributes = new { #class = "form-control", #placeholder = "Zip" } })
#Html.ValidationMessageFor(model => model.Zip, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-1 col-md-offset-1 col-sm-offset-1 col-xs-offset-1 col-lg-5 col-md-5 col-sm-5 col-xs-5">
#Html.EditorFor(model => model.HomePhone, new { htmlAttributes = new { #class = "form-control", #placeholder = "Home Phone" } })
#Html.ValidationMessageFor(model => model.HomePhone, "", new { #class = "text-danger" })
</div>
<div class="col-lg-5 col-md-5 col-sm-5 col-xs-5">
#Html.EditorFor(model => model.CellPhone, new { htmlAttributes = new { #class = "form-control", #placeholder = "Cell Phone" } })
#Html.ValidationMessageFor(model => model.CellPhone, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-1 col-md-offset-1 col-sm-offset-1 col-xs-offset-1 col-lg-5 col-md-5 col-sm-5 col-xs-5">
#Html.EditorFor(model => model.Website, new { htmlAttributes = new { #class = "form-control", #placeholder = "Website" } })
#Html.ValidationMessageFor(model => model.Website, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-1 col-md-offset-1 col-sm-offset-1 col-xs-offset-1 col-lg-5 col-md-5 col-sm-5 col-xs-5">
#Html.EditorFor(model => model.IMAddress, new { htmlAttributes = new { #class = "form-control", #placeholder = "IM Address" } })
#Html.ValidationMessageFor(model => model.IMAddress, "", new { #class = "text-danger" })
</div>
</div>
</fieldset>
<fieldset>
<legend>Project</legend>
#Html.Partial("_Projects", Model)
</fieldset>
<div class="form-group">
<div>
<button type="submit" id="btnCustomerProjectCreate" class="btn btn-primary col-offset-2"><span class="glyphicon glyphicon-save"></span>Create</button>
</div>
</div>
</div>
}
My Partial View (noted above as #Html.Partial) is as follows:
#model Models.ViewModels.Projects.ProjectDTO
<div class="form-group">
<div class="col-lg-offset-1 col-md-offset-1 col-sm-offset-1 col-xs-offset-1 col-lg-11 col-md-11 col-sm-11 col-xs-11">
#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">
<div class="col-lg-offset-1 col-md-offset-1 col-sm-offset-1 col-xs-offset-1 col-lg-11 col-md-11 col-sm-11 col-xs-11">
#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">
<div class="col-lg-offset-1 col-md-offset-1 col-sm-offset-1 col-xs-offset-1 col-lg-11 col-md-11 col-sm-11 col-xs-11">
#Html.DropDownListFor(model => model.CategoryID, new SelectList(ViewBag.Categories, "CategoryID", "Description", ViewBag.CategoryID == null ? null : ViewBag.CategoryID), "-- Select Category --", new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.CategoryID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-1 col-md-offset-1 col-sm-offset-1 col-xs-offset-1 col-lg-11 col-md-11 col-sm-11 col-xs-11">
#Html.DropDownListFor(model => model.PriorityID, new SelectList(ViewBag.Priorities, "PriorityID", "Description", ViewBag.PriorityID == null ? null : ViewBag.Priority), "-- Select Priority --", new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PriorityID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-1 col-md-offset-1 col-sm-offset-1 col-xs-offset-1 col-lg-11 col-md-11 col-sm-11 col-xs-11">
#Html.DropDownListFor(model => model.StatusID, new SelectList(ViewBag.Statuses, "StatusID", "Description", ViewBag.StatusID == null ? null : ViewBag.StatusID), "-- Select Status --", new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.StatusID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-1 col-md-offset-1 col-sm-offset-1 col-xs-offset-1 col-lg-11 col-md-11 col-sm-11 col-xs-11">
#Html.EditorFor(model => model.Quote, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Quote, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-1 col-md-offset-1 col-sm-offset-1 col-xs-offset-1 col-lg-11 col-md-11 col-sm-11 col-xs-11">
#Html.EditorFor(model => model.Notes, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Notes, "", new { #class = "text-danger" })
</div>
</div>

I think you are confusing yourself of what to pass where and how it will be rendered.
You have two models
CustomerDTO
ProjectDTO
You are Creating a ViewModel and passing it to View that is of type CustomerDTO. When you Pass same model to partial #Html.Partial("_Projects", Model) , You are passing CustomerDTO. However, partial view is expecting to recieve ProjectDTO. Means You should pass ProjectsDTO.
Now I can see that You have
public virtual ICollection Projects { get; set; }
set in there, I am assuming Projects Contains ProjectDTO model in it by looking at your namespace declaration.
Pass ProjectDTO model with foreach loop using
#foreach(var item in Model.Projects)
{
#Html.Partial(item.ProjectDTO)
}
This will work. However, this is not best practice. You should get ICollection and use DisplayTemplate to Render your data.
Please post, your ProjectsDTO model and also post what is expected output that you want so that We can answer specifically of where are things going wrong,
Update
I think now I understand where things are going Wrong. I will try to keep it simple while I explain.
You said , Your models are coming back as null. There could be three reasons for that to happen.
You never Instantiated your model. Do it by (CustomerDTO cDTO = new CustomerDTO()
Get it from somewhere , for example CustomerDTO cDTO = getCustomerDTO() where getCustomerDTO() function returs CustomerDTO model.
Even though you had a Model with you , you never passed it to View. You can do this in Action something like follow.
Public ActionResult ShowCustomer()
{
CustomerDTO cDTO = new CustomerDTO();
return View("ViewName" , cDTO);
}
Moving to Second issue where You want to have a superClass that contains Multiple Classes.
You have DTO are your DomainModels, whose job is to get data from Database, I think they are doing Their Job. NOw If Both of those Domain models needs to go to View, you need to Create ViewModel that will look something like this,
public class DTOViewModel
{
public CustomerDTO Customer {get ; set ;}
public ProjectsDTO Projects {get; set;}
}
Then you can Create Action that will look something like following,
public ActionResult DTOViews()
{
DTOViewModel model = new DTOViewModel();
model.Customer = getCustomer();
model.Projects = getProjects();
return View("YourView" , model); //Make sure ViewName exist in Respective Folder.
}
Then in View You may have following;
#model namespace.DTOViewModel
<h2> This is your main View. </h2>
#Html.Partial("_CustomerPartial" , model.Customer )
#Html.Partial("_ProjectPartial" , model.Projects )
Hope this helps.

Check the generated Html of the helpers. You need the name of the form elements to be something like "CustomerProjectDto.CustomerDto.Description". With Partials I thing you get "Description".
Try to use your own Editor Templates that create the right html for complex nodells.
Check this article to read about it. https://lostechies.com/jimmybogard/2011/09/07/building-forms-for-deep-view-model-graphs-in-asp-net-mvc/

Related

I tried Bootstrap DateTimePicker in ASP.NET MVC 5 but it's not working

I'm really new to ASP.NET MVC even the Web,I tried to build it on VS 2019,this is NOT the .net core project,it's the .NET for Win project,I tried to build a datetimepicker within the text input, so I tried to build to view like the below
#model log_viewer.Models.QueryParms
#{
ViewBag.Title = "QueryLog";
}
<h2>Query</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Query </h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.mdno, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.mdno, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.mdno, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.startdate, htmlAttributes: new { #class = "control-label col-md-2" })
#*<div class="col-md-10">
#Html.EditorFor(model => model.startdate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.startdate, "", new { #class = "text-danger" })
</div>*#
<div class="col-md-10">
<div class="input-group" id="datetimepicker">
#Html.EditorFor(model => model.startdate, new { htmlAttributes = new { #class = "datetimepicker form-control" } })
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
#Html.ValidationMessageFor(model => model.startdate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.enddate, htmlAttributes: new { #class = "control-label col-md-2" })
#*<div class="col-md-10">
#Html.EditorFor(model => model.enddate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.enddate, "", new { #class = "text-danger" })
</div>*#
<div class="col-md-10">
<div class="input-group" id="datetimepicker">
#Html.EditorFor(model => model.enddate, new { htmlAttributes = new { #class = "form-control" } })
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
#Html.ValidationMessageFor(model => model.enddate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Summit" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
My models are as below
public class QueryParms
{
[DisplayName("Contains Strings")]
public string mdno { get; set; }
[DisplayName("Begin Date")]
[DisplayFormat(DataFormatString = "{0:yyyy-mm-dd}", ApplyFormatInEditMode = true)]
public DateTime startdate { get; set; }
[DisplayName("End Date")]
[DisplayFormat(DataFormatString = "{0:yyyy-mm-dd}", ApplyFormatInEditMode = true)]
public DateTime enddate { get; set; }
}
When I clicked the datetime picker, it just not working, nothing happened

How can i show DisplayName label before and after editor (English + Arabic ) in MVC?

I want to create multi-language system using MVC (English and Arabic) , I want to use one view for both languages , i created the Login view based on the following model :
public partial class WEBSITE_USERS
{
[DisplayName("ID / Iqamam No - رقم الهوية او الاقامة")]
[Required(ErrorMessage ="This field is required يجب ادخال رقم الهوية المسجل في الملف الطبي ")]
public string ID_NO { get; set; }
[DisplayName("Mobile No - رقم الجوال")]
[Required(ErrorMessage = "Mobile No is required - يجب ادخال رقم الجوال المسجل في الملف ")]
public string MOBILE { get; set; }
[DisplayName("Medical Record No - رقم الملف")]
[Required(ErrorMessage = "File No is required يجب ادخال رقم الملف الطبي ")]
}
Now the DisplayName appeared on left side ,
How can i show the English label on left side and Arabic label on right side of editor to show like this for example :
ID/Iqama No ----------------- رقم الهوية او الاقامة
Now its appear all in left side like this :
ID / Iqamam No - رقم الهوية او الاقامة ---------------------------
this is the view code
#model kaashtaif.Models.WEBSITE_USERS
#{
ViewBag.Title = "Login Window - شاشة تسجيل الدخول";
}
<h2>Login</h2>
#using (Html.BeginForm("Authorise","Login",FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.ID_NO, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ID_NO, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ID_NO, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.MOBILE, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.MOBILE, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.MOBILE, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.PATIENT_NO, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PATIENT_NO, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PATIENT_NO, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-md-10">
<label>#Html.DisplayFor(model => model.LoginErrorMessage)</label>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Login" class="btn btn-default" />
<input type="reset" name="name" value="Clear" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
and this is screen shot of view
Fastest way of doing it is changing your markup and manually using Html.DisplayNameFor() then split that string up.
Repeat this process for the rest of the input fields/ form-group.
<div class="form-group">
<div class="col-md-3">
#Html.DisplayNameFor(x => x.ID_NO).ToString().Split('-')[0]
</div>
<div class="col-md-6">
#Html.EditorFor(model => model.ID_NO, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ID_NO, "", new { #class = "text-danger" })
</div>
<div class="col-md-3">
#Html.DisplayNameFor(x => x.ID_NO).ToString().Split('-')[1]
</div>
</div>
What's happening here is we're getting the value of DisplayName attribute which is [DisplayName("ID / Iqamam No - رقم الهوية او الاقامة")] and since you have a delimiter which is a hyphen, we're splitting the string into two using that - or hyphen then displaying the string by index.

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

Validate required model only

I'm using two models, Login & Signup Model in a View.
public class Login
{
[Required(ErrorMessage ="User ID Required.")]
public string UserID { get; set; }
[Required(ErrorMessage ="Password Required")]
public string Password { get; set; }
}
public class SignUp
{
[Required (ErrorMessage ="User ID Required")]
public string UserID { get; set; }
[Required (ErrorMessage ="Name Required")]
public string Name { get; set; }
[Required (ErrorMessage ="Mail ID Required")]
public string MailID { get; set; }
[Required(ErrorMessage ="Password Required")]
public string Password { get; set; }
[Required(ErrorMessage ="Confirm Password Required")]
[Compare (nameof(Password), ErrorMessage ="Password does not match")]
public string ConfirmPassword { get; set; }
}
when I click Login button, it validates both the models. How to validate the model separately?
Used following codes in controller
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(string Command, Login Login)
{
if (Command == "SIGNUP")
{
return RedirectToAction("Contact");
}
else
{
if (ModelState.IsValidField("USERID") && ModelState.IsValidField("PASSWORD"))
{
return RedirectToAction("About");
}
}
return View();
}
Index.cshtml VIEW CODE:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="HolderForm">
<div class="col-md-6">
<div class="form-horizontal">
<h4>Login</h4>
<hr />
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.Login.UserID, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "USER ID" } })<br>
#Html.ValidationMessageFor(o => o.Login.UserID,"", new {#class= "LoginValidation" } )
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.Login.Password, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "PASSWORD" } })<br>
#Html.ValidationMessageFor(o => o.Login.Password,"", new { #class = "LoginValidation" })
#ViewBag.Posted
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
#ViewBag.Posted
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit"
value="LOGIN"
id="btn_Login"
name="Command"
class="btn btn-default" />
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-horizontal">
<h4>SignUp</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.SignUp.UserID, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "USER ID" } })<br>
#Html.ValidationMessageFor(o => o.SignUp.UserID,"", new { #class = "LoginValidation" } )
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.SignUp.Name, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "NAME" } })<br>
#Html.ValidationMessageFor(o => o.SignUp.Name, "", new { #class = "LoginValidation" })
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.SignUp.MailID, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "MAIL ID" } })<br>
#Html.ValidationMessageFor(o => o.SignUp.MailID, "", new { #class = "LoginValidation" })
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.SignUp.Password, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "PASSWORD", #type = "password" } })<br>
#Html.ValidationMessageFor(o => o.SignUp.Password, "", new { #class = "LoginValidation" })
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.SignUp.ConfirmPassword, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "CONFIRM PASSWORD", #type = "password" } })<br>
#Html.ValidationMessageFor(o => o.SignUp.ConfirmPassword, "", new { #class = "LoginValidation" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type= "submit" value="SIGNUP"
id="btn_Login"
name="Command"
class="btn btn-default" />
</div>
</div>
</div>
</div>
</div>
}
Above code place on the view using two different model.
Please help and also suggest me where to learn ASP.NET (Beginner level)?
you add Login and SignUp in one Form
#using (Html.BeginForm()){
...
}
try this
<div class="HolderForm">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="col-md-6">
<div class="form-horizontal">
<h4>Login</h4>
<hr />
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.Login.UserID, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "USER ID" } })<br>
#Html.ValidationMessageFor(o => o.Login.UserID,"", new {#class= "LoginValidation" } )
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.Login.Password, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "PASSWORD" } })<br>
#Html.ValidationMessageFor(o => o.Login.Password,"", new { #class = "LoginValidation" })
#ViewBag.Posted
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
#ViewBag.Posted
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit"
value="LOGIN"
id="btn_Login"
name="Command"
class="btn btn-default" />
</div>
</div>
</div>
</div>
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="col-md-6">
<div class="form-horizontal">
<h4>SignUp</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.SignUp.UserID, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "USER ID" } })<br>
#Html.ValidationMessageFor(o => o.SignUp.UserID,"", new { #class = "LoginValidation" } )
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.SignUp.Name, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "NAME" } })<br>
#Html.ValidationMessageFor(o => o.SignUp.Name, "", new { #class = "LoginValidation" })
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.SignUp.MailID, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "MAIL ID" } })<br>
#Html.ValidationMessageFor(o => o.SignUp.MailID, "", new { #class = "LoginValidation" })
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.SignUp.Password, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "PASSWORD", #type = "password" } })<br>
#Html.ValidationMessageFor(o => o.SignUp.Password, "", new { #class = "LoginValidation" })
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.SignUp.ConfirmPassword, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "CONFIRM PASSWORD", #type = "password" } })<br>
#Html.ValidationMessageFor(o => o.SignUp.ConfirmPassword, "", new { #class = "LoginValidation" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type= "submit" value="SIGNUP"
id="btn_Login"
name="Command"
class="btn btn-default" />
</div>
</div>
</div>
</div>
</div>
}

Client side validation not working on password

I Have the following register view
#model YFA.Models.RegisterViewModel
#{
ViewBag.Title = "Register";
}
<h2 class="col-md-offset-1">#ViewBag.Title</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-group">
<div class="row">
<div class="col-md-3 col-md-offset-1">
#Html.LabelFor(model => model.BranchId, htmlAttributes: new { #class = "control-label" })
#Html.DropDownListFor(model => model.BranchId, new SelectList(Model.Branches, "BranchId", "BranchName", 0), "Please Select", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.BranchId, "", new { #class = "text-danger" })
</div>
</div>
</div>
<h3 class="col-md-offset-1">Name</h3>
<div class="form-group">
<div class="row">
<div class="col-md-3 col-md-offset-1">
#Html.LabelFor(model => model.FirstName, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { #class = "form-control", placeholder = "John" } })
#Html.ValidationMessageFor(model => model.FirstName, "", new { #class = "text-danger" })
</div>
<div class="col-md-4">
#Html.LabelFor(model => model.LastName, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.LastName, new { htmlAttributes = new { #class = "form-control", placeholder = "Smith" } })
#Html.ValidationMessageFor(model => model.LastName, "", new { #class = "text-danger" })
</div>
</div>
</div>
<h3 class="col-md-offset-1">Contact Details</h3>
<div class="form-group">
<div class="row">
<div class="col-md-4 col-md-offset-1">
#Html.LabelFor(model => model.Mobile, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.Mobile, new { htmlAttributes = new { #class = "form-control", placeholder = "07724 567890" } })
#Html.ValidationMessageFor(model => model.Mobile, "", new { #class = "text-danger" })
</div>
</div>
<div class="row">
<div class="col-md-3 col-md-offset-1">
#Html.LabelFor(model => model.Email, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.Email, new { htmlAttributes = new { #class = "form-control", placeholder = "me#provider.com" } })
#Html.ValidationMessageFor(model => model.Email, "", new { #class = "text-danger" })
</div>
<div class="col-md-4">
#Html.LabelFor(model => model.ConfirmEmail, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.ConfirmEmail, new { htmlAttributes = new { #class = "form-control", placeholder = "me#provider.com" } })
#Html.ValidationMessageFor(model => model.ConfirmEmail, "", new { #class = "text-danger" })
</div>
</div>
</div>
<h3 class="col-md-offset-1">Dates</h3>
<div class="form-group">
<div class="row">
<div class="col-md-3 col-md-offset-1">
#Html.LabelFor(model => model.DateOfBirth, htmlAttributes: new { #class = "control-label" })
#Html.TextBoxFor(model => model.DateOfBirth, new { #class = "form-control", placeholder = "01/12/80" })
#Html.ValidationMessageFor(model => model.DateOfBirth, "", new { #class = "text-danger" })
</div>
<div class="col-md-2">
#Html.LabelFor(model => model.Joined, htmlAttributes: new { #class = "control-label" })
#Html.TextBoxFor(model => model.Joined, new { #class = "form-control", placeholder = "01/12/10" })
#Html.ValidationMessageFor(model => model.Joined, "", new { #class = "text-danger" })
</div>
</div>
</div>
<h3 class="col-md-offset-1">Password</h3>
<div class="form-group">
<div class="row">
<div class="col-md-3 col-md-offset-1">
#Html.LabelFor(model => model.Password, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.Password, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Password, "", new { #class = "text-danger" })
</div>
<div class="col-md-4">
#Html.LabelFor(model => model.ConfirmPassword, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.ConfirmPassword, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ConfirmPassword, "", new { #class = "text-danger" })
</div>
</div>
</div>
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<div class="col-md-offset-1 col-md-10">
<input type="submit" class="btn btn-default" value="Register" />
</div>
</div>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$(function () {
$("#DateOfBirth").datepicker({
format: "dd/mm/yyyy",
startDate: "-120y",
endDate: "-10y",
startView: 2,
calendarWeeks: true,
defaultViewDate: { year: 1975, month: 01, day: 01 }
});
});
$(function () {
$("#Joined").datepicker({
format: "dd/mm/yyyy",
startDate: "-20y",
endDate: "1y",
startView: 2,
calendarWeeks: true,
defaultViewDate: { year: 2010, month: 01, day: 01 }
});
});
</script>
}
The client side validation works fine for every field except the password field. it will warn if the password isn't the correct length but won't warn about the need for a capital or non alpha numeric character.
I'm using asp.net mvc identity.
The view model section for password is:
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
And the post controller is:
//
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
var now = DateTime.Now;
UserManager.AddClaim(user.Id, new Claim(ClaimTypes.GivenName, model.FirstName));
//Add the new club details to the database
var Instructor = new Instructor
{
FirstName = model.FirstName,
LastName = model.LastName,
Joined = model.Joined,
Email = model.Email,
Mobile = model.Mobile,
BranchId = model.BranchId,
LGVDrv = model.LGVDrv,
MiniBusDrv = model.MiniBusDrv,
Operational = model.Operational,
ApplicationUserId = user.Id,
};
db.Instructors.Add(Instructor);
db.SaveChanges();
var currentUser = UserManager.FindByName(user.UserName);
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
return RedirectToAction("Index", "Home");
}
else
{
AddErrors(result);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
When posting the form it returns the view because var result fair to succeed.
Following the comment above I amended the viewModel by adding a regular expression to it as follows:
[Required]
[RegularExpression(#"^(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z].*[a-z].*[a-z]).{8,20}$",
ErrorMessage = "Password is not valid, it must be between 8 - 20 characters and contain a number and a capital letter")]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }

Resources