2

I'm trying to create a basic registration form that takes in an address with a state from a drop down list. I can't seem to extract the data from the drop down into my model that contains a state object. I've tried creating a custom model binder as shown below. When I debug the ModelState is valid, but the state is always null.

Models:

public class AccountInfo { public virtual Guid accoundID { get; set; } public virtual string city { get; set; } public virtual string email_address { get; set; } public virtual string fax_number { get; set; } public virtual string first_name { get; set; } public virtual string last_name { get; set; } public virtual string mailing_address { get; set; } public virtual string phone_number { get; set; } public virtual State state { get; set; } public virtual string zip_code { get; set; } } public class State { public virtual int ID { get; set; } public virtual string text { get; set; } public virtual string value { get; set; } } 

Model Binder:

 public class StateModelBinder : IModelBinder { private RepositoryDB Database; public object BindModel( ControllerContext controllerContext, ModelBindingContext bindingContext ) { var key = bindingContext.ModelName + ".state"; var value = bindingContext.ValueProvider.GetValue(key); if (value == null) { return null; } var result = new State(); Database = new RepositoryDB(ConfigurationManager. ConnectionStrings["ConnectionString"].ConnectionString); try { var query = from s in Database.States where s.value == value.ToString() select new State() { text = s.text, ID = s.ID, value = s.value }; result = (State)query.ToList().ElementAt(0); } catch (Exception ex) { bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex.Message); bindingContext.ModelState.SetModelValue(key, value); } return result; } 

Controller:

[HttpPost] public ActionResult Index(AccountInfo accountModel) { try { if (ModelState.IsValid) { Database.Account.Add(accountModel); Database.SaveChanges(); return Redirect(Url.Action("Success")); } } catch (Exception ex) { ModelState.AddModelError(String.Empty, ex); } // invalid info - return with error message //repop select lists GetStates(); return View(accountModel); } public void GetStates() { IEnumerable<SelectListItem> states = from s in Database.States select new SelectListItem { Text = s.text, Value = s.value }; ViewBag.state = states.ToList(); } 

View:

@Html.LabelFor(model => model.state, "*State") @Html.DropDownListFor(model => model.state, (IEnumerable<SelectListItem>)ViewBag.state) 
2
  • What are you doing? Why custom model binder? Why ViewBag? Why not view models?CommentedAug 1, 2012 at 16:30
  • I am trying to store the "State" (as in a mailing address) as an object inside the AccountInfo class. I'm populating the drop down with a linq query from a simple table on the database that has every possible state. Could you demonstrate how to use a viewmodel instead of my implementation?CommentedAug 1, 2012 at 17:25

1 Answer 1

3

Here is your problem:

@Html.DropDownListFor(model => model.state, (IEnumerable<SelectListItem>)ViewBag.state) 

Binding to model.State cannot work because that is a complex type:

public class State { public virtual int ID { get; set; } public virtual string text { get; set; } public virtual string value { get; set; } } 

If you think about it the only thing the form is going to post back is the value of the selected drop down item like "MN" (Minnesota) and not a full class. (You haven't serialized a "State" class to each drop down list item's value, just the primary key of each state hopefully) You need to make your state on the model be a string or int depending on what type that primary key is of your state like so:

public class AccountInfo { //... public virtual string/int State { get; set; } //... } 

From there you can re-hydrate your State object if you'd like from the unique identifier of a state (which should be the value that is posted back to the server as a string or int for example)

0

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.