MVC ViewModel not being sent back to controller - c#

I've seen multiple instances of this question. Be that as it may, I still cannot figure out what the issue is with this post method not passing back the model to the controller. I've looked at naming conventions between the model being passed into the controller, as well as whether or not the read only fields were being passed in if I had removed them. Other than that, it might be the BindAttribute, binding the RoleIds of the multi-select to the model.
Here's my code:
the model:
public class UserDetail
{
public Guid Id { get; set; }
public List<string> RoleIds { get; set; }
public string DomainName { get; set; }
public string Name { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserName { get; set; }
public string EmailAddress { get; set; }
public string PhysicalDeliveryOfficeName { get; set; }
public string TenantDisplayId { get; set; }
public Boolean InitPassword { get; set; }
public Boolean Active { get; set; }
public Boolean SystemAdmin { get; set; }
public ICollection<RoleDetail> Roles { get; set; }
public IEnumerable<SelectedRoles> SelectedRoles { get; set; }
public MultiSelectList RoleOptions { get; set; }
public UserDetail()
{
Id = Id;
RoleIds = RoleIds;
FirstName = FirstName;
LastName = LastName;
Name = Name;
Active = Active;
EmailAddress = EmailAddress;
SystemAdmin = SystemAdmin;
}
}
cshtml:
#model IzendaEmbedded.Models.UserDetail
#using (Html.BeginForm("EditActiveDirectoryUser","ActiveDirectory",
FormMethod.Post, new {userDetail = Model}))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<nav aria-label="breadcrumb">
<ol class="breadcrumb" style="height: 100px; padding-top: 20px; padding-left: 140px; background-color: #FFFFFF">
<li class="breadcrumb-item" style="font-family: arial; font-size:40px"><a href=#Url.Action("Index", "Home")>Izenda</a></li>
<li class="breadcrumb-item active" aria-current="page" style="font-family: arial; font-size:40px"><a href=#Url.Action("Parse", "ActiveDirectory")>Active Directory</a></li>
<li class="breadcrumb-item active" aria-current="page" style="font-family: arial; font-size:40px">Edit Izenda User</li>
</ol>
</nav>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-4">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control", #readonly = "readonly" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.UserName, "Account Name", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-4">
#Html.EditorFor(model => model.UserName, new { htmlAttributes = new { #class = "form-control", #readonly = "readonly" } })
#Html.ValidationMessageFor(model => model.UserName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FirstName, "First Name", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-4">
#Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { #class = "form-control", #readonly = "readonly" } })
#Html.ValidationMessageFor(model => model.FirstName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LastName, "Last Name", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-4">
#Html.EditorFor(model => model.LastName, new { htmlAttributes = new { #class = "form-control", #readonly = "readonly" } })
#Html.ValidationMessageFor(model => model.LastName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.EmailAddress, "Email Address", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-4">
#Html.EditorFor(model => model.EmailAddress, new { htmlAttributes = new { #class = "form-control", #readonly = "readonly" } })
#Html.ValidationMessageFor(model => model.EmailAddress, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Roles, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-4">
#Html.ListBoxFor(model => model.RoleIds, Model.RoleOptions, new {#class = "form-control"})
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Active, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-4">
<div class="checkbox">
#Html.EditorFor(model => model.Active)
#Html.ValidationMessageFor(model => model.Active, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-4">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
The controller post method:
[HttpPost]
public async Task<ActionResult> EditActiveDirectoryUser([Bind(Include =
"Id, Name, RoleIds")] UserDetail userDetail)
{
//save logic
}

Related

edit profile view asp.net-mvc5

I am quite new to asp.net mvc5, and in my app I want to retrieve user info in their profile.
In profile action I'm trying to display the user info and allow them to edit their info too.
But when I run the program I am getting the edit and display view empty.
I am expecting to see the user previous info when they're trying to edit for example.
here is a picture of what I want:
this is my action :
[HttpGet]
public ActionResult DriverProfile()
{
var userManager = HttpContext.GetOwinContext().GetUserManager<AppUserManager>();
var authManager = HttpContext.GetOwinContext().Authentication;
ProfileModel driver = new ProfileModel();
IdentityUser theUser = new IdentityUser() { UserName = driver.email, Email = driver.email };
driver = new ProfileModel(theUser);
return View("DriverProfile", driver);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult DriverProfile(ProfileModel profile)
{
var manager = new UserManager<IdentityUser>(new UserStore<IdentityUser>(new RidesDbContext()));
IdentityUser theUser = new IdentityUser() { UserName = profile.email, Email = profile.email };
IdentityResult theResult = manager.Create(theUser, profile.PasswordHash);
var currentUser = manager.FindById(User.Identity.GetUserId());
currentUser.UserName = profile.email;
currentUser.Email = currentUser.Email;
return Redirect("DriverProfile");
}
I have the profile model as the following:
public class ProfileModel
{
public ProfileModel()
{
}
public ProfileModel(IdentityUser theUser)
{
}
[Display(Name = "Id")]
public int driverId { get; set; }
[Display(Name = "First Name")]
[Required(ErrorMessage = "Pleas Enter Your First Name")]
public string firstName { get; set; }
[Display(Name = "Last Name")]
[Required(ErrorMessage = "Pleas Enter Your Last Name")]
public string lastName { get; set; }
[Display(Name = "Email Address")]
[DataType(DataType.EmailAddress)]
[Required(ErrorMessage = "Pleas Enter Your Email Address")]
[RegularExpression(".+\\#.+\\..+", ErrorMessage = "Please Enater a Valid Email Address")]
public string email { get; set; }
[Display(Name = "Mobile Number")]
[Required(ErrorMessage = "Pleas Enter Your Mobile Number")]
public string phoneNumber { get; set; }
[Display(Name = "Address")]
[Required(ErrorMessage = "Pleas Enter Your Address")]
public string Address { get; set; }
[Display(Name = "City")]
[Required(ErrorMessage = "Pleas Enter Your City")]
public string city { get; set; }
[Display(Name = "State")]
[Required(ErrorMessage = "Pleas Enter Your state")]
public string state { get; set; }
[Display(Name = "Car")]
[Required(ErrorMessage = "Please Identify Your Car")]
public string car { get; set; }
[Display(Name = "Driver's License")]
[Required(ErrorMessage = "Please Enter Your Driver's Licende Number")]
public string driverslicense { get; set; }
[Display(Name = "Profile Image")]
[Required]
public byte[] profileImg { get; set; }
public string profileImgType { get; set; }
[Display(Name = "License Image")]
[Required]
public byte[] licenseImg { get; set; }
public string licenseImgType { get; set; }
[Display(Name = "Password")]
[DataType(DataType.Password)]
[Required(ErrorMessage = "Please Enter a password")]
public string PasswordHash { get; set; }
}
How would I get the user info in their profile with an edit option?
I would appreciate your help. Thank you.
Edit:
the view is as the following:
#model RidesApp.Models.ProfileModel
#{
ViewBag.Title = "DriverProfile";
Layout = "~/Views/Shared/DriversViewPage.cshtml";
}
<h2>DriverProfile</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>ProfileModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.driverId)
<div class="form-group">
#Html.LabelFor(model => model.firstName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.firstName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.firstName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.lastName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.lastName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.lastName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.email, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.email, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.phoneNumber, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.phoneNumber, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.phoneNumber, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Address, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Address, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Address, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.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">
#Html.LabelFor(model => model.state, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.state, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.state, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.car, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.car, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.car, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.driverslicense, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.driverslicense, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.driverslicense, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.profileImgType, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.profileImgType, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.profileImgType, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.licenseImgType, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.licenseImgType, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.licenseImgType, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.PasswordFor(model => model.PasswordHash, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PasswordHash, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PasswordHash, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Edit Profile" class="btn btn-default" />
</div>
</div>
</div>
}
If I understand the question correctly, You want to edit the IdentityUser Class right?
Given that you already assign values in your controller.
First, we add the IdentityUser class to your ProfileModel Class
public class ProfileModel{
public IdentityUser User{get;set;}
//other profilemodel properties
}
on your view:
<div class="form-group">
#Html.LabelFor(model => model.User.Email, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.User.Email, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.User.Email, "", new { #class = "text-danger" })
</div>
</div>
or if you just want to show up some values in editing,
you need to assign the value of your ProfileModel
Controller:
ProfileModel driver = new ProfileModel();
//code that assigns values to each property
driver.email = "sample#sample.com";
return View("DriverProfile",driver);

.submit() Prevents Form from Submitting

I have a fairly simple form and ViewModel which works fine, but when I add this JS, the form no longer submits to the controller:
$("#crmtForm").submit(function (e) {
console.log('submit');
});
Why? I'm pretty sure this is supposed to work... Please can someone help this makes no sense.
Controller
[HttpPost]
public async Task<ActionResult> Create(CRMTItemViewModel viewModel)
{
viewModel.CreatedBy = System.Security.Claims.ClaimsPrincipal.Current.Claims.FirstOrDefault(c => c.Type == "name").Value;
if (viewModel.ProjectTitle == "spinnertest")
return View();
// Insert db rows?
var crmtItem = await crmtItemsManager.InsertItem(viewModel);
// Initialise workspace on a seperate thread
new Thread(() =>
{
var projectManager = new ProjectManager();
projectManager.ProcessRequest(crmtItem);
}).Start();
// Redirect to item
return RedirectToAction("Details", new { id = crmtItem.Id });
}
Form
#using (Html.BeginForm("Create", "CrmtItems", FormMethod.Post, new { id = "crmtForm" }))
{
<div class="form-horizontal">
<h4>New Project Workspace Form</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.ProjectTitle, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ProjectTitle, new { htmlAttributes = new { #class = "form-control", required = "required" } })
#Html.ValidationMessageFor(model => model.ProjectTitle, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ProjectStage, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EnumDropDownListFor(model => model.ProjectStage, new { #class = "form-control", required = "required" })
#Html.ValidationMessageFor(model => model.ProjectStage, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CRMTNumber, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CRMTNumber, new { htmlAttributes = new { #class = "form-control", required = "required" } })
#Html.ValidationMessageFor(model => model.CRMTNumber, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.GbSNumber, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.GbSNumber, new { htmlAttributes = new { #class = "form-control", required = "required" } })
#Html.ValidationMessageFor(model => model.GbSNumber, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Confidential, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.CheckBoxFor(model => model.Confidential, new { #class = "form-control", #style = "height:17px;" })
#Html.ValidationMessageFor(model => model.Confidential, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => Model.SelectedTags, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.HiddenFor(m => m.Id, new { required = "required" })
#Html.ListBoxFor(m => m.SelectedTags, new SelectList(users, "UserName", "DisplayName"), new { #class = "teamSelecter", name = "states[]", multiple = "multiple", style = "display:none; width:100%;", required = "required" })
#Html.ValidationMessageFor(model => model.SelectedTags, "", new { #class = "text-danger" })
<p id="pmWarning" class="text-danger" hidden>Please select one or more project managers</p>
</div>
</div>
<br />
<button id="formSubmit" class="btn btn-default btn-lg pull-right" type="submit" value="submit">Submit</button>
<div class="loader pull-right" hidden></div>
</div>
}
ViewModel
public class CRMTItemViewModel
{
public int Id { get; set; }
[Display(Name = "Project Title")]
[Remote("DoesProjectTitleExist", "CRMTItems", HttpMethod = "POST",
ErrorMessage = "Workspace for that project title already exists.")]
public string ProjectTitle { get; set; }
[Display(Name = "Project Stage")]
public ProjectStage? ProjectStage { get; set; }
[Display(Name = "CRMT Number")]
[Remote("DoesCrmtNumberExist", "CRMTItems", HttpMethod = "POST",
ErrorMessage = "Workspace for that CRMT number already exists.")]
public int? CRMTNumber { get; set; }
[Display(Name = "GBS Number")]
[Remote("DoesGbSNumberExist", "CRMTItems", HttpMethod = "POST",
ErrorMessage = "Workspace for that GBS project number already exists.")]
public int? GbSNumber { get; set; }
public bool Confidential { get; set; }
[Display(Name = "Project Managers")]
public IEnumerable<string> SelectedTags { get; set; }
}
I tried your code in my project its working,may be issue with your jquery version,one more thing I found when I was created scaffolding view with this model it automatically created #section Scripts {
#Scripts.Render("~/bundles/jqueryval")
} at end of view page,
when I removed this script from page then able to call post method otherwise not.

C# MVC Razor form with a dynamic array of objects [duplicate]

This question already has an answer here:
Submit same Partial View called multiple times data to controller?
(1 answer)
Closed 5 years ago.
So I'm trying to create a Invoice form. In this form I want to fill in some customer details and add products, all in the same form.
I created a static example of how I want it to look:
The idea is to manually fill in a product, and if I want another product, I'd press the green plus glyphicon and add another product.
By clicking on the create button I want to submit this entire form with the customer details and the array/list of added products.
This is the code I have so far:
This is the view model that I use inside the view:
public class InvoiceViewModel
{
public Enums.Gender Gender { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string StreetName { get; set; }
public string HouseNumber { get; set; }
public string PostCode { get; set; }
public string City { get; set; }
public string PhoneNumber { get; set; }
public string EmailAddress { get; set; }
public List<InvoiceItemViewModel> InvoiceItems { get; set; }
}
This is the InvoiceItemViewModel that I use inside the partial view:
public class InvoiceItemViewModel
{
public string Name { get; set; }
public Enums.UnitType UnitType { get; set; }
public int Ammount { get; set; }
public decimal PriceWithoutVAT { get; set; }
}
This is the Create 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.Gender, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EnumDropDownListFor(model => model.Gender)
#Html.ValidationMessageFor(model => model.Gender, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FirstName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.FirstName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LastName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.LastName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LastName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.PostCode, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PostCode, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PostCode, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.HouseNumber, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.HouseNumber, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.HouseNumber, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.StreetName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.StreetName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.StreetName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.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">
#Html.LabelFor(model => model.PhoneNumber, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PhoneNumber, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PhoneNumber, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.EmailAddress, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.EmailAddress, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.EmailAddress, "", new { #class = "text-danger" })
</div>
</div>
<hr />
<h4>Products</h4>
<div class="container">
<div class="row">
<div class="col-md-6">Name</div>
<div class="col-md-2">Unit(s)</div>
<div class="col-md-2">Ammount</div>
<div class="col-md-2">Price</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-11">
#Html.Partial("~/Views/Invoice/InvoiceItem.cshtml")
</div>
</div>
<div class="row">
<div class="col-md-11">
#Html.Partial("~/Views/Invoice/InvoiceItem.cshtml")
</div>
</div>
<div class="row">
<div class="col-md-11">
#Html.Partial("~/Views/Invoice/InvoiceItem.cshtml")
</div>
<div class="col-md-1">
<span class="glyphicon glyphicon-plus" style="color: green;"></span>
</div>
</div>
</div>
</div>
<br />
<br />
<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>
}
And this is the partial view for an invoice item:
<div class="col-md-6">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
</div>
<div class="col-md-2">
#Html.EnumDropDownListFor(model => model.UnitType)
</div>
<div class="col-md-2">
#Html.EditorFor(model => model.Ammount, new { htmlAttributes = new { #class = "form-control" } })
</div>
<div class="col-md-2">
#Html.EditorFor(model => model.PriceWithoutVAT, new { htmlAttributes = new { #class = "form-control" } })
</div>
So my question is, how do I add multiple invoice items to my form that I can use in the controller when I submit? I'm afraid that it's going to be a lot of javascript DOM manipulations.
Have a hidden template of the row on your page, then on the click of plus button, you can read the innerhtml of the template and append to list container.
Sample code
var templatehtml = $('#template')[0].innerHTML;
var newhtml = templatehtml
.replace(new RegExp('{{counter}}', 'g'), counter.toString())
.replace('{{counter++}}', (Number(counter) + Number(1)).toString());
$('#container').append(newhtml);
This will get you started, however it's not the most optimal code and the recommended way is to use a template library like JSRender

System.ArgumentNullException' occurred in System.Core.dll but was not handled in user code [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 6 years ago.
Net I was trying to do a Edit for uploading a image but now whenever I edit it crashes and gives 'System.ArgumentNullException' occurred in System.Core.dll but was not handled in user code'. This all started when I tried to implement an edit for the image upload. It crashes on the edit.cshtml page, I have placed a comment right where it crashes. Any help would be really appreciated, if you require any more information please let me know
AnimalsController
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "LatinNameID,CommonNameID,LatinName,CommonName,GenusID,SpeciesID,Description,FamilyID,CountryID,ContinentID,OrderID")] Animal animal, HttpPostedFileBase upload,string latinID,string commonID)
{
var animalToUpdate = db.Animals.Find(latinID,commonID);
//Does a check to see if entry exists in database
if ((db.Animals.Any(ac => ac.LatinName.Equals(animal.LatinName))) || (db.Animals.Any(ac => ac.CommonName.Equals(animal.CommonName))))
{
ModelState.AddModelError("LatinName", "Already Exists");
ModelState.AddModelError("CommonName", "Duplicate Entry");
}
else
{
if (ModelState.IsValid)
{
if (upload != null && upload.ContentLength > 0)
{
if (animalToUpdate.Files.Any(f => f.FileType == FileType.Avatar))
{
db.File.Remove(animalToUpdate.Files.First(f => f.FileType == FileType.Avatar));
}
var avatar = new File
{
FileName = System.IO.Path.GetFileName(upload.FileName),
FileType = FileType.Avatar,
ContentType = upload.ContentType
};
using (var reader = new System.IO.BinaryReader(upload.InputStream))
{
avatar.Content = reader.ReadBytes(upload.ContentLength);
}
animalToUpdate.Files = new List<File> { avatar };
}
db.Entry(animal).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
}
ViewBag.ContinentID = new SelectList(db.Continents, "ContinentID", "ContinentName", animal.ContinentID);
ViewBag.CountryID = new SelectList(db.Countries, "CountryID", "CountryName", animal.CountryID);
ViewBag.FamilyID = new SelectList(db.Families, "FamilyID", "FamilyName", animal.FamilyID);
ViewBag.GenusID = new SelectList(db.Genus, "GenusID", "GenusName", animal.GenusID);
ViewBag.OrderID = new SelectList(db.Orders, "OrderID", "OrderName", animal.OrderID);
ViewBag.SpeciesID = new SelectList(db.Species, "SpeciesID", "SpeciesName", animal.SpeciesID);
return View(animal);
}
Edit View
<h2>Edit</h2>
#using (Html.BeginForm("Edit", "Animals", null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Animal</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.LatinNameID)
#Html.HiddenFor(model => model.CommonNameID)
<div class="form-group">
#Html.LabelFor(model => model.LatinName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.LatinName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LatinName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CommonName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CommonName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.CommonName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.GenusID, "GenusID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("GenusID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.GenusID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SpeciesID, "SpeciesID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("SpeciesID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.SpeciesID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Description, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#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.FamilyID, "FamilyID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("FamilyID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.FamilyID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CountryID, "CountryID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("CountryID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.CountryID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ContinentID, "ContinentID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("ContinentID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.ContinentID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.OrderID, "OrderID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("OrderID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.OrderID, "", new { #class = "text-danger" })
</div>
</div>
//Crashes here
#if (Model.Files.Any(f => f.FileType == FileType.Avatar))
{
<div class="form-group">
<span class="control-label col-md-2"><strong>Current Avatar</strong></span>
<div class="col-md-10">
<img src="~/File?id=#Model.Files.First(f => f.FileType == FileType.Avatar).FileId" alt="avatar" />
</div>
</div>
}
<div class="form-group">
#Html.Label("Avatar", new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input type="file" id="Avatar" name="upload" />
</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", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Model
//Animal
public class Animal
{
[Key, Column(Order = 0)]
public string LatinNameID { get; set; }
public string LatinName { get; set; }
[Key, Column(Order = 1)]
public string CommonNameID { get; set; }
public string CommonName { get; set; }
public string GenusID { get; set; }
public string SpeciesID { get; set; }
public string Description { get; set; }
public string FamilyID { get; set; }
public string CountryID { get; set; }
public string ContinentID { get; set; }
public string OrderID { get; set; }
public virtual Continent Continent { get; set; }
public virtual Genus Genus { get; set; }
public virtual Species Species { get; set; }
public virtual Family Family { get; set; }
public virtual Country Country { get; set; }
public virtual Order Order { get; set; }
public virtual ICollection<File> Files { get; set; }
}
//File
public class File
{
public int FileId { get; set; }
[StringLength(255)]
public string FileName { get; set; }
[StringLength(100)]
public string ContentType { get; set; }
public byte[] Content { get; set; }
public FileType FileType { get; set; }
public string LatinNameID { get; set; }
public string CommonNameID { get; set; }
public virtual Animal Animal { get; set; }
}
The error that you are getting suggests that you are calling a method with a null argument somewhere in your code. Since it crashes with the if statement beginning with Model.Files.Any(f => f.FileType == FileType.Avatar), I would verify that Model.Files is not null before proceeding.
The code could look like the following:
#if (Model.Files != null && Model.Files.Any(f => f.FileType == FileType.Avatar))
{
<div class="form-group">
<span class="control-label col-md-2"><strong>Current Avatar</strong></span>
<div class="col-md-10">
<img src="~/File?id=#Model.Files.First(f => f.FileType == FileType.Avatar).FileId" alt="avatar" />
</div>
</div>
}
If Model.Files should never be null, then you might need to investigate why that value is not being set as well.

Slightly more complex "create" form in ASP.NET w/Entity Framework and MVC

Here is a sample of my models. There is a Supply Receipt that holds custom models for Block, Grower, and a collection of SupplyReceiptLine:
public class SupplyReceipt
{
[Key]
public int Id { get; set; }
[Required]
public string LoadNumber { get; set; }
[Required]
public DateTime Date { get; set; }
public string Notes { get; set; }
[Required]
public Block Block { get; set; }
[Required]
public Contact Grower { get; set; }
[Required]
public ICollection<SupplyReceiptLine> SupplyReceiptLines { get; set; }
}
And I don't think it's necessary for my question but here is an example for my Contact model (used for Grower):
public class Contact
{
[Key]
public int Id { get; set; }
[Required]
public string Title { get; set; }
public string Note { get; set; }
[Display(Name="Billing Address")]
public virtual Address BillingAddress { get; set; }
[Display(Name = "Shipping Address")]
public virtual Address ShippingAddress { get; set; }
[Display(Name = "Show as Supplier")]
public bool IsSupplier { get; set; }
[Display(Name = "Show as Customer")]
public bool IsCustomer { get; set; }
[Display(Name = "Show as Grower")]
public bool IsGrower { get; set; }
[Display(Name = "Show as Bin Owner")]
public bool IsBinOwner { get; set; }
}
Now I'm having multiple problems:
Regular MVC Scaffolding (Entity Framework Model) doesn't like Grower, Block, or Supply Receipt Lines. I understand Supply Receipt Lines needs logic behind it, but I don't understand why I had to work so hard to create a drop down select box for Grower and Block. These types are well defined (with Ids and Key attributes) and there is data in the database for these items.
Could anyone explain what I'm missing in my model above that MVC / EF Scaffolding doesn't understand? A lot of tutorials online show this automatically being done. I had to resort to manually placing an Html.DropDownListFor in my view, passing it a new SelectList built from my database context. I also had to update the controller post method to include an integer for Grower and integer for Block, and manually lookup the Grower & Block by id, assign them back to the model, before adding my Supply Receipt to the database.
I couldn't figure this out. Supply Receipt Lines is an ICollection, it should hold multiple Supply Receipt Line. How do I update my create view, and my controller, so that I can add multiple supply receipt lines within this same form?
Here is an example screenshot to go along with number 2:
Here is some of the other code associated with this "create" method, including the editors. Thanks for your time.
(Controller Post Method)
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(SupplyReceipt supplyReceipt, int Grower, int Block, ICollection<SupplyReceiptLine> supplyReceiptLines)
{
// supplyReceiptLines turns up null! So does supplyReceipt.SupplyReceiptLines
// Need Grower and Block For Some reason
supplyReceipt.Grower = db.Contacts.Where(model => model.Id.Equals(Grower)).First();
supplyReceipt.Block = db.Blocks.Where(model => model.Id.Equals(Block)).First();
if (ModelState.IsValid)
{
db.SupplyReceipts.Add(supplyReceipt);
if (supplyReceiptLines != null && supplyReceiptLines.Any())
{
db.SupplyReceiptLines.AddRange(supplyReceiptLines);
}
db.SaveChanges();
return RedirectToAction("Index");
}
return View(supplyReceipt);
}
(Create Form)
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>SupplyReceipt</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.LoadNumber, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.LoadNumber, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LoadNumber, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Date, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Date, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Date, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Grower, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Grower, new SelectList(Db.Contacts, "Id", "Title"), "Select a Grower", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Grower, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Block, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Block, new SelectList(Db.Blocks, "Id", "Title"), "Select a Block", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Block, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Notes, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Notes, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Notes, "", new { #class = "text-danger" })
</div>
</div>
<hr />
<div id="supplyReceiptLines">
#Html.EditorFor(model => model.SupplyReceiptLines, "SupplyReceiptLines")
</div>
<div class="form-group text-right">
Add a row
</div>
<hr />
<div class="form-group">
<div class="text-right">
<button type="submit" value="Create" class="btn btn-default btn-success">Create Supply Receipt</button>
</div>
</div>
</div>
}
(Editor Template)
#model SupplyReceiptLine
#{
ModelContext Db = new ModelContext();
}
<div class="form-group form-inline">
#Html.HiddenFor(model => model.Id)
<div class="col-sm-1">
#Html.LabelFor(model => model.Qty, htmlAttributes: new { #class = "" })
#Html.EditorFor(model => model.Qty, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Qty, "", new { #class = "text-danger" })
</div>
<div class="col-sm-1">
#Html.LabelFor(model => model.Pack, htmlAttributes: new { #class = "" })
#Html.DropDownListFor(model => model.Pack, new SelectList(Db.Packs, "Id", "Title"), "", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Pack, "", new { #class = "text-danger" })
</div>
<div class="col-sm-1">
#Html.LabelFor(model => model.Size, htmlAttributes: new { #class = "" })
#Html.DropDownListFor(model => model.Size, new SelectList(Db.Sizes, "Id", "Title"), "", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Size, "", new { #class = "text-danger" })
</div>
<div class="col-sm-3">
#Html.LabelFor(model => model.Variety, htmlAttributes: new { #class = "" })
#Html.DropDownListFor(model => model.Variety, new SelectList(Db.Varieties, "Id", "Title"), "", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Variety, "", new { #class = "text-danger" })
</div>
<div class="col-sm-3">
#Html.LabelFor(model => model.Grade, htmlAttributes: new { #class = "" })
#Html.DropDownListFor(model => model.Grade, new SelectList(Db.Grades, "Id", "Title"), "", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Grade, "", new { #class = "text-danger" })
</div>
<div class="col-sm-3">
#Html.LabelFor(model => model.BinOwner, htmlAttributes: new { #class = "" })
#Html.DropDownListFor(model => model.BinOwner, new SelectList(Db.Contacts, "Id", "Title"), "", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.BinOwner, "", new { #class = "text-danger" })
</div>
</div>

Categories

Resources