ViewModel property doesn't bind into controller action parameter - asp.net-mvc

My problem is that my ViewModel property doesn't bind into an action parameter.
I think it'll be more clear if i just give you my code.
I have a model as follows:
namespace Sima3.Models
{
using System;
using System.Collections.Generic;
public partial class Usuario
{
public string Login { get; set; }
public string NombreCompleto { get; set; }
public short Organigrama { get; set; }
public int Interno { get; set; }
public string EMail { get; set; }
}
}
And i added DataAnnotations to this partial class in another file (Because this model was generated automatically by EntityFramework), note the remote validation on Login property:
namespace Sima3.Models
{
[MetadataType(typeof(UsuarioMetaData))]
public partial class Usuario
{
}
public class UsuarioMetaData
{
[Display(Name = "Nombre de Usuario")]
[Remote("NoExisteUsuario", "Validation")]
[Required]
public string Login { get; set; }
[Display(Name = "Nombre y Apellido")]
[Required]
public string NombreCompleto { get; set; }
[Display(Name = "Sector")]
[Required]
public short Organigrama { get; set; }
[Required]
public int Interno { get; set; }
[EmailAddress]
[Required]
public string EMail { get; set; }
}
}
Now, i have a ViewModel wich contains a property of type Usuario and some other stuff needed to render my View:
namespace Sima3.ViewModels.PedidoViewModels
{
public class AgregarViewModel
{
public Usuario Usuario { get; set; }
public Pedido Pedido { get; set; }
public SelectList ListaSectores { get; set; }
public SelectList ListaEstados { get; set; }
public SelectList ListaPrioridades { get; set; }
public SelectList ListaTipos { get; set; }
public SelectList ListaDirecciones { get; set; }
}
}
And my view looks as follows (I'll only post part of it, if u need to see more let me know):
#using (Ajax.BeginForm("Crear", "Usuario", null,
new AjaxOptions
{
OnSuccess = "UsuarioCreadoSuccess",
HttpMethod = "Post"
}
, new { #class = "form-horizontal", id = "FormUsuario" }))
{
#Html.AntiForgeryToken()
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title title">Nuevo Usuario</h4>
</div>
<div class="modal-body">
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.Usuario.Login, new { #class = "col-lg-4 control-label" })
<div class="col-lg-7">
#Html.TextBoxFor(model => model.Usuario.Login, new { #class = "form-control"})
#Html.ValidationMessageFor(model => model.Usuario.Login)
</div>
</div>
Alright, the important part is the TextBoxFor, it renders me the next HTML:
<input class="form-control valid" data-val="true" data-val-remote="'Nombre de Usuario' is invalid." data-val-remote-additionalfields="*.Login" data-val-remote-url="/Validation/NoExisteUsuario" data-val-required="El campo Nombre de Usuario es obligatorio." id="Usuario_Login" name="Usuario.Login" type="text" value="">
As you see, the textbox name is: name="Usuario.Login"
And my controller action wich gets called by the Remote validation looks like this:
public JsonResult NoExisteUsuario([Bind(Prefix="Usuario")]string Login)
{
Usuario usuario = db.Usuarios.Find(Login);
if (usuario != null)
{
var MensajeDeError = string.Format("El usuario {0} ya existe", Login);
return Json(MensajeDeError, JsonRequestBehavior.AllowGet);
}
else
{
return Json(true, JsonRequestBehavior.AllowGet);
}
}
I set a breakpoint in this Action and it gets hit, but Login comes in null.
I checked with google chrome's debugger the http request header and it shows the form is getting submitted like this: Usuario.Login: asdasdasd.
The question is simple, how can i make it bind?
By the way, i'm using MVC5.
Thanks.

Well, i finally got it working, it seems i was setting the Prefix binding attribute wrongly.
Now my action looks like this:
public JsonResult NoExisteUsuario([Bind(Prefix="Usuario.Login")]string login)
{
Usuario usuario = db.Usuarios.Find(login);
if (usuario != null)
{
var MensajeDeError = string.Format("El usuario {0} ya existe", login);
return Json(MensajeDeError, JsonRequestBehavior.AllowGet);
}
else
{
return Json(true, JsonRequestBehavior.AllowGet);
}
}

Related

How to select SelectListItem inside a Razor View

I have a Model which i want to edit (Location).This model has a field called ActivityId.I am sending an array of ActivityId-s via ViewData to the view and transform them to a SelectList.
I want the ActivityId field (long) of the Location to be set with the selected item from the dropdownlist (string) - i need a conversion done somehow from string to long before entering the Post Action of the controller.(EditConfirmed)
Models:
[Table("location")]
public partial class Location
{
public Location()
{
StoryLocation = new HashSet<StoryLocation>();
UserStoryLocation = new HashSet<UserStoryLocation>();
}
[Column("id", TypeName = "bigint(20)")]
public long Id { get; set; }
[Column("description")]
[StringLength(255)]
public string Description { get; set; }
[Column("name")]
[StringLength(255)]
public string Name { get; set; }
[Column("activity_id", TypeName = "bigint(20)")]
public long? ActivityId { get; set; }
[ForeignKey("ActivityId")]
[InverseProperty("Location")]
public Activity Activity { get; set; }
}
}
[Table("activity")]
public partial class Activity
{
public Activity()
{
Location = new HashSet<Location>();
}
[Column("activity_id", TypeName = "bigint(20)")]
public long ActivityId { get; set; }
[Column("description")]
[StringLength(255)]
public string Description { get; set; }
[Column("name")]
[StringLength(255)]
public string Name { get; set; }
[Column("type")]
[StringLength(255)]
public string Type { get; set; }
[InverseProperty("Activity")]
public ICollection<Location> Location { get; set; }
}
Controller:
[HttpGet]
public IActionResult Edit(long id = 0)
{
Location loc = this.context.Locations.Find(id);
if (loc == null)
{
return NotFound();
}
ViewData[Constants.ViewData.TActivities]=this.context.Activities
.Select(elem=>
new SelectListItem
{
Text=elem.Name,
Value=elem.ActivityId.ToString()
}
).ToList();
return View(loc);
}
View
#using AdminMVC.Models
#using AdminMVC.ConfigConstants
#using Newtonsoft.Json
#model AdminMVC.Models.Location
#{
List<SelectListItem> dropActivities=ViewData[Constants.ViewData.TActivities] as List<SelectListItem>;
}
<html>
<head>
</head>
<body>
<div id="form">
</div>
<div id="page">
#using (Html.BeginForm("Edit","Location",FormMethod.Post))
{
<div id="table">
<label>Set Location:</label>
<table border="">
#Html.DisplayFor(x=>x.Id)
<tr>
<td>#Html.DisplayNameFor(x=>x.Name)</td>
<td>#Html.EditorFor(x=>x.Name)</td>
</tr>
<tr>
<td>#Html.DisplayNameFor(x=>x.Description)</td>
<td>#Html.EditorFor(x=>x.Description)</td>
</tr>
<div>
<label >Select Activity:</label>
#Html.DropDownList("Activity",dropActivities) //i need to somehow convert the selected value from the dropdown to long before the form is sent to the controller
</div>
</table>
</div>
<div id="control-panel">
<input type="submit" value="Edit">
</div>
}
</body>
</div>
</html>
Post to Controller
[HttpPost, ActionName("Edit")]
public IActionResult EditConfirmed(Location editLoc)
{
if (ModelState.IsValid)
{
this.context.Entry(editLoc).State = EntityState.Modified;
this.context.SaveChanges();
return RedirectToAction("Index");
}
return View(editLoc);
}
P.S:So far the ActivityId of the Location sent to the Post Action is null.I need it to be long.
I solved this problem using the ViewData component.I would first serialize the SelectList using NewtonSoft then i would add it to the ViewData dictionary.When rendering the view i would use the DropDownList razor Html Helper method.
Model
public class FixedLocation
{
[Column("id", TypeName = "bigint(20)")]
public long Id { get; set; }
[Column("coords")]
[StringLength(255)]
public string Coords { get; set; }
[Column("name")]
[StringLength(255)]
[Required]
public string Name { get; set; }
[Column("google_id")]
[StringLength(255)]
[Required]
public string GoogleId { get; set; }
}
Extension method for getting a List of SelectListItem
public static IEnumerable<SelectListItem> ToSelectList<T,Tkey,Tvalue>(
this IQueryable<T> myenum,
Func<T,(Tkey,Tvalue)>kvpair)
{
return myenum.Select(elem=>kvpair(elem))
.Select(tuple=>new SelectListItem{
Text=tuple.Item1.ToString(),
Value=tuple.Item2.ToString()
});
}
Controller:
public IActionResult Create()
{
Location targetLocation = new Location();
ViewData[Constants.ViewData.TFixedLocations]=
this.context.FixedLocation
.ToSelectList<FixedLocation,string,long>
(elem=>(elem.Name,elem.Id)).ToList();
return View(targetLocation);
}
View:
#using AdminMVC.Models
#model AdminMVC.Models.Location
#using AdminMVC.ConfigConstants
#{
dropFixedLocations=ViewData[Constants.ViewData.TFixedLocations] as List<SelectListItem>;
}
<div>
<label >Select FixedLocation:</label>
#Html.DropDownListFor(x=>Model.Id,dropFixedLocations)
</div>

Error in my upload page after i changed my model [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 6 years ago.
I added the code to show many checkboxes from my table (HairTags) and in my form CreationUpload.cshtml i got the following error :
An exception of type 'System.NullReferenceException' occurred in
App_Web eba142hb.dll but was not handled in user code Additional
information: Object reference not set to an instance of an object.
Object reference not set to an instance of an object.
<div class="col-md-12">
#for (int i = 0; i < Model.CreationHairTags.Count; i++)
{
#Html.CheckBoxFor(m => Model.CreationHairTags[i].IsChecked)
#Model.CreationHairTags[i].Text
#Html.HiddenFor(m => Model.CreationHairTags[i].Value)
#Html.HiddenFor(m => Model.CreationHairTags[i].Text)<br />
}
</div>
this is my model Creation.cs (in bold the added code)
namespace HairCollection3.Models
{
public class Creation
{
public string UserId { get; set; }
[Key]
public int CreationId { get; set; }
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(ViewRes.ValidationStrings))]
[Display(Name = "Sex", ResourceType = typeof(ViewRes.Names))]
public string CreationSex { get; set; }
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(ViewRes.ValidationStrings))]
[Display(Name = "CreationTitle", ResourceType = typeof(ViewRes.NamesCreation))]
[StringLength(2000)]
[AllowHtml]
public string CreationTitle { get; set; }
public string CreationPhotoBis { get; set; }
public string Creationtag { get; set; }
public virtual ICollection<CreationLike> CreationLikes { get; set; }
}
public class CreationLike
{
public int CreationId { get; set; }
public string UserId { get; set; }
public virtual ApplicationUser User { get; set; }
[Key]
public int CreationLikeId { get; set; }
public virtual Creation ParentCreation { get; set; }
}
public class HairTag
{
[Key]
public int HairTagId { get; set; }
[Required]
public string HairTagTitle { get; set; }
[Required]
public string HairTagType { get; set; }
[Required]
public int HairTagOrder { get; set; }
}
***//CHECKBOXES
public class HairTagModel
{
[Key]
public int Value { get; set; }
public string Text { get; set; }
public bool IsChecked { get; set; }
}
public class HairTagList
{
private ApplicationDbContext creationdb = new ApplicationDbContext();
public HairTagList()
{
var HairTagList = creationdb.HairTags.ToList();
List<HairTagModel> obj = new List<HairTagModel>();
foreach (var tags in HairTagList)
{
obj.Add(new HairTagModel
{
Text = tags.HairTagTitle,
Value = tags.HairTagId,
IsChecked = false
});
}
this.CreationHairTags = obj;
}
public List<HairTagModel> CreationHairTags { get; set; }
//public List<HairTagModel> ListHairTags { get; set; }
}
public class CreationHairTagsModel
{
public Creation Creation { get; set; }
public List<HairTagModel> CreationHairTags { get; set; }
}
}***
My controller CreationController.cs
// GET: /Creation/CreationUpload
[Authorize]
public ActionResult CreationUpload()
{
CreationHairTagsModel creation = new CreationHairTagsModel();
return View(creation);
//return View();
}
// POST: /Creation/CreationUpload
// Afin de déjouer les attaques par sur-validation, activez les propriétés spécifiques que vous voulez lier. Pour
// plus de détails, voir http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public ActionResult CreationUpload([Bind(Include = "CreationId,CreationSex,CreationTitle,CreationPhotoBis,CreationHairTags")] CreationHairTagsModel creation, IEnumerable<HttpPostedFileBase> files)
{
if (ModelState.IsValid)
{
// update each field manually
foreach (var file in files)
{
if (file != null)
{
if (file.ContentLength > 0)
{
....CODE UPLOAD HIDDEN....
//Avoid Script
var CreationTitletocheck = Regex.Replace(creation.Creation.CreationTitle, #"<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>", string.Empty);
CreationTitletocheck = Regex.Replace(CreationTitletocheck, #"(?></?\w+)(?>(?:[^>'""]+|'[^']*'|""[^""]*"")*)>", string.Empty);
creation.Creation.CreationTitle = CreationTitletocheck;
//Tags
StringBuilder sb = new StringBuilder();
foreach (var item in creation.CreationHairTags)
{
if (item.IsChecked)
{
sb.Append(item.Text + ",");
}
}
creation.Creation.Creationtag = sb.ToString();
creation.Creation.UserId = User.Identity.GetUserId();
db.Creations.Add(creation.Creation);
db.SaveChanges();
}
}
}
}
//UserId
return RedirectToAction("CreationList", "Creation", new { UserId = User.Identity.GetUserId() });
}
return View(creation);
}
My page of upload CreationUpload.cshtml
#model HairCollection3.Models.CreationHairTagsModel
#using Microsoft.AspNet.Identity
#{
ViewBag.Title = ViewRes.NamesCreation.CreationUploadTitle;
}
<div class="col-sm-12 col-md-12 chpagetop">
<h1>#ViewRes.Shared.PublishAPhoto</h1>
<hr />
#using (Html.BeginForm("CreationUpload", "Creation", FormMethod.Post, new { id = "CreationUpload", enctype = "multipart/form-data", onsubmit = "$('#creationloading').show(); $('#creationform').hide();" }))
{
#Html.AntiForgeryToken()
<div class="col-md-12" id="creationloading" style="display:none">
<div id="progress">
<p>#ViewRes.Shared.UploadPhotoProgress<strong>0%</strong></p>
<progress value="5" min="0" max="100"><span></span></progress>
</div>
</div>
<div class="col-md-12" id="creationform">
<div class="col-md-12">
#Html.ValidationMessageFor(m => m.Creation.CreationSex)
#Html.RadioButtonFor(m => m.Creation.CreationSex, "F", new { #checked = true }) #ViewRes.Shared.WomanHairstyle #Html.RadioButtonFor(m => m.Creation.CreationSex, "M") #ViewRes.Shared.ManHairstyle
</div>
<div class="col-md-12">
#Html.ValidationMessageFor(m => m.Creation.CreationTitle)
#Html.TextBoxFor(m => m.Creation.CreationTitle, new { #class = "inputplaceholderviolet wid100x100", placeholder = HttpUtility.HtmlDecode(Html.DisplayNameFor(m => m.Creation.CreationTitle).ToHtmlString()), onfocus = "this.placeholder = ''", onblur = "this.placeholder = '" + HttpUtility.HtmlDecode(Html.DisplayNameFor(m => m.Creation.CreationTitle).ToHtmlString()) + "'" })
</div>
<div class="col-md-12">
#for (int i = 0; i < Model.CreationHairTags.Count; i++)
{
#Html.CheckBoxFor(m => Model.CreationHairTags[i].IsChecked)
#Model.CreationHairTags[i].Text
#Html.HiddenFor(m => Model.CreationHairTags[i].Value)
#Html.HiddenFor(m => Model.CreationHairTags[i].Text)<br />
}
</div>
<div class="col-md-12" style="text-align: center">
<p style="display: inline-block">
<input type="file" accept="image/*" onchange="loadFile(event)" name="files" id="file1" translate="yes" data-val="true" data-val-required="A File is required." class="wid100x100" /><label for="file1"></label>
<img id="output" style="max-width:200px;"/>
</p>
</div>
<div class="col-sm-12 col-md-12 chpagetopdiv">
<button type="submit" title="#ViewRes.Shared.Publish"><span class="glyphicon glyphicon-share-alt"></span> #ViewRes.Shared.Publish</button>
</div>
</div>
}
</div>
What is wrong in my code please help and explain ?
Important: In C#, every collection must be initialized before being accessed
The error occurs when you are trying to access from the View to the collection CreationHairTags, which is not initialized. Replace your model to initialize collection in the class constructor:
public class CreationHairTagsModel
{
public Creation Creation { get; set; }
public List<HairTagModel> CreationHairTags { get; set; }
public CreationHairTagsModel()
{
CreationHairTags = new List<HairTagModel>();
}
}

Autogentrated Entity models always true even custom class implemented

I am using autogenerated entity model classes and than i used partial class with metadata to put validations on auto genetrated classes like below.
public class tblDepartmentCustom
{
[Key]
public int DepartmentId { get; set; }
[Required(ErrorMessage = "Department name is required")]
public string DepartmentName { get; set; }
}
[MetadataType(typeof(tblDepartmentCustom))]
public partial class tblDepartmentMaster
{
}
The original class that was generated by entity framework is given below.
public partial class tblDepartmentMaster
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public tblDepartmentMaster()
{
this.tblDesignationMasters = new HashSet<tblDesignationMaster>();
}
public int DepartmentId { get; set; }
public string DepartmentName { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<tblDesignationMaster> tblDesignationMasters { get; set; }
}
So the problem here is that whenever i try to validated model state it comes out to be true.below is the code.
#model EmployeeManager.Models.tblDepartmentCustom
#{
ViewBag.Title = "InsertDepartment";
Layout = "~/Views/Shared/_AdminLayout.cshtml";
}<div class="col-md-4">
#using (Html.BeginForm("InsertDepartment", "Departments", FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary()
<span class="error-class">#ViewBag.FoundError</span>
<br />
<label>Department Name</label>
#Html.TextBoxFor(m => m.DepartmentName, new { #class = "form-control" })
<br />
<input type="submit" class="btn btn-info" value="Add Department" />
}
</div>
And the action below.
[HttpGet]
public ActionResult InsertDepartment()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
[ActionName("InsertDepartment")]
public ActionResult InsertDepartmentPost()
{
using (PMSEntities dc = new PMSEntities())
{
tblDepartmentMaster dm = new tblDepartmentMaster();
TryUpdateModel(dm);
if(ModelState.IsValid)
{
dc.tblDepartmentMasters.Add(dm);
dc.SaveChanges();
return View("_Success");
}
else
{
ViewBag.FoundError = "Department name is required.";
return View();
}
}
}
In order for partial classes to work, both partials must have the same namespace. You don't have to move the actual files around your file structure, just edit the namespace of tblDepartmentCustom to match that of tblDepartmentMaster.

ViewData item key 'SelectedAustraliaStateId' is of type 'System.String' but must be of type 'IEnumerable<SelectListItem>'

I am not able to save the record after implementing the drop down field. Can someone please correct my code.
Create.cshtml
#model SomeIndianShit.Models.Accommodation
#{
ViewBag.Title = "Advertise Accommodation";
}
<form name="datapluspics" method="post" enctype="multipart/form-data">
#Html.ValidationSummary(true)
<fieldset>
<legend>Accommodation</legend>
<div class="editor-label">
#Html.LabelFor(model => model.State)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.SelectedAustraliaStateId, Model.AustraliaStates)
</div>
<p>
<input type="submit" value=" Save " />
</p>
</fieldset>
</form>
My Model:
public class AustraliaStates
{
[Key]
public string AustraliaStateId { get; set; }
public string AustraliaStateName { get; set; }
}
public class Accommodation
{
[Key]
public string A_Unique_Id { get; set; }
[Display(Name = "Ad Id")]
public string Ad_Id { get; set; }
[Display(Name = "Posted By")]
public string User { get; set; }
[Display(Name = "Street")]
public string Street { get; set; }
[Required]
[Display(Name = "Suburb")]
public string Suburb { get; set; }
[Required]
[Display(Name = "State")]
public string State { get; set; }
public byte[] Picture1 { get; set; }
public string SelectedAustraliaStateId { get; set; }
public IEnumerable<SelectListItem> AustraliaStates { get; set; }
}
AccommodationController.cs
// GET: /Accommodation/Create
[Authorize]
public ActionResult Create()
{
var model = new Accommodation
{
AustraliaStates = db.AustraliaStates
.ToList()
.Select(x => new SelectListItem
{
Text = x.AustraliaStateName,
Value = x.AustraliaStateId
})
};
return View(model);
}
/ POST: /Accommodation/Create
[Authorize]
[HttpPost]
public ActionResult Create(Accommodation accommodation, HttpPostedFileBase file1, HttpPostedFileBase file2, HttpPostedFileBase file3)
{
if (ModelState.IsValid)
{
// save and redirect
// ...blah blah...
//blah blah...
db.Accommodation.Add(accommodation);
//Save in Database
db.SaveChanges();
return RedirectToAction("Index");
}
// repopulate SelectList properties [I THINK THIS IS WRONG]
var model = new Accommodation
{
AustraliaStates = db.AustraliaStates
.ToList()
.Select(x => new SelectListItem
{
Text = x.AustraliaStateName,
Value = x.AustraliaStateId
})
};
return View(accommodation);
}
After filling the form, when save button is clicked, the following error message is displayed
The ViewData item that has the key 'SelectedAustraliaStateId' is of type 'System.String' but must be of type 'IEnumerable'.
In your HttpPost controller action you need to repopulate the correct property on the model that you are passing to the view, i.e. set the AustraliaStates on your model the same way you are doing in your GET action:
accommodation.AustraliaStates = db.AustraliaStates
.ToList()
.Select(x => new SelectListItem
{
Text = x.AustraliaStateName,
Value = x.AustraliaStateId
});
return View(accommodation);

MVC4 dropdownlist error

Based on this post
Second answerI tried to create a dropdown list for my register page.
Register page has a field where you can select the PossibleAccessRight for the user while registering him/her which should be saves in AccessRight Attribute.
Right now i can't even show the items in dropdownlist
My model looks like this
public class UserModel
{
public int UserId { get; set; }
[Required]
[EmailAddress]
[StringLength(100)]
[DataType(DataType.EmailAddress)]
[Display(Name = "Email ID ")]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
[StringLength(20,MinimumLength = 6)]
[Display(Name = "Password ")]
public string Password { get; set; }
[Required]
[Display(Name = "First Name ")]
public string FirstName { get; set; }
[Required]
[Display(Name = "Last Name ")]
public string LastName { get; set; }
[Required]
[Display(Name = "Address ")]
public string Address { get; set; }
public List<string> PossibleRights;
[Required]
[Display(Name = "Access Rights")]
public string AccessRight { get; set; }
public UserModel()
{
PossibleRights = new List<string>()
{
{"High"},
{"Low"},
};
}
}
in controller i have this in registeration method which is httppost method
[HttpGet]
public ActionResult Register()
{
return View();
}
[HttpPost]
public ActionResult Register(Models.UserModel user)
{
var rights = new UserModel();
if (ModelState.IsValid)
{
using (var db = new DBaseEntities())
{
var crypto = new SimpleCrypto.PBKDF2();
var encrpPass = crypto.Compute(user.Password);
var sysUser = db.SystemUsers.Create();
sysUser.FirstName = user.FirstName;
sysUser.Email = user.Email;
sysUser.Password = encrpPass;
sysUser.PasswordSalt = crypto.Salt;
db.SystemUsers.Add(sysUser);
db.SaveChanges();
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("","Login data is incorrect.");
}
return View(rights);
}
View for this method looks like this
<div class="editor-label">#Html.LabelFor(u=> u.FirstName)</div>
<div class="editor-field"> #Html.TextBoxFor(u=> u.FirstName)</div>
<br/>
<div class="editor-label">#Html.LabelFor(u=> u.LastName)</div>
<div class="editor-field"> #Html.TextBoxFor(u=> u.LastName)</div>
<br/>
<div class="editor-label">#Html.LabelFor(u=> u.Address)</div>
<div class="editor-field"> #Html.TextBoxFor(u=> u.Address)</div>
<br/>
<div class="editor-label">#Html.LabelFor(u=> u.Email)</div>
<div class="editor-field"> #Html.TextBoxFor(u=> u.Email)</div>
<br/>
<div class="editor-label">#Html.LabelFor(u=> u.Password)</div>
<div class="editor-field"> #Html.PasswordFor(u=> u.Password)</div>
<br/>
<div class="editor-label">#Html.LabelFor(u=> u.AccessRight)</div>
<div class="editor-field"> #Html.DropDownListFor(u=> u.PossibleRights, new SelectList(Model.PossibleRights))</div>//error at this line(NullReference exception)
<br/>
<input type="submit" value="Register"/>
any idea what I'm doing wrong? Also, is my approach to show the items in dropdownlist good? Can you suggest better idea if any?
If you want to display any info on the view, you have to provide this info to the view first. Right now this code:
public ActionResult Register()
{
return View();
}
does not provide any info at all. Model for the view is created with default constructor, which means that model object is empty, therefore nothing is displayed on the view (particularly in the dropdown list). What you need is some initialization like this:
public ActionResult Register()
{
UserModel model = new UserModel();
model.PossibleRights = new List<string>{"Right1", "Right2", "Right3"};
// or go to db, or whatever
return View(model);
}
Besides dropdown returns selected value when posted, which is string representing a right in this case. So you need to introduce some field in the model to store the selection:
public class UserModel
{
...
public List<string> PossibleRights;
public string SelectedRight;
...
}
Usage on view is the following:
#Html.DropDownListFor(u => u.SelectedRight, new SelectList(Model.PossibleRights))

Resources