views:

657

answers:

2

I can't seem to get the value of a select list to populate the value of the parent object. I'm using a wrapper object to bind to so that I have access to the values needed for the SelectList as well as the object which needs the value. I'm willing to bet I'm missing something basic but I can't find it.

I have these models:

    public class Status
    {
        public virtual int Id { get; protected set; }
        public virtual string Name { get; set; }
        public virtual bool IsClosed { get; set; }

        public override string ToString()
        {
            return Name;
        }
    }
    public class Issue
    {
        public virtual int Id { get; protected set; }
        public virtual string Title { get; set; }
        public virtual string Description { get; set; }
        public virtual Status Status { get; set; }
        public virtual DateTime CreatedOn { get; set; }
        public virtual DateTime UpdatedOn { get; set; }

    }

And a FormViewModel (from NerdDinner examples) to contain the list of Statuses

    public class IssueFormViewModel
    {
        public Issue Issue { get;  set; }
        public SelectList Statuses { get;  set; }
        public IssueFormViewModel(Issue issue, IList<Status> statuses)
        {
            Issue = issue;
            Statuses = new SelectList(statuses, "Id", "Name", statuses[1].Id );
        }

        public IssueFormViewModel() { }

    }

My Create Actions on the Controller look like...

    public ActionResult Create()
    {
        IList<Status> statuses;
        Issue issue = new Issue();
        // NHibernate stuff getting a List<Status>
        return View(new IssueFormViewModel(issue,statuses));
    } 
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create(IssueFormViewModel issueFormView)
    { // At this point issueFormView.Issue.Status == null
      // ...
    }

My Issue object is bound partially except the status using these names in the View:

<p>
            <label for="Issue.Title">Title:</label>
            <%= Html.TextBox("Issue.Title", Model.Issue.Title)%>
            <%= Html.ValidationMessage("Title", "*") %>
        </p>
<p>
            <label for="Statuses">Status:</label>
            <!-- also tried "Issue.Status" -->
            <%= Html.DropDownList("Statuses", Model.Statuses)%>
            <%= Html.ValidationMessage("Status", "*")%>
        </p>
A: 

I tried the dropdown list on my computer and it works, you should make sure NHibernate is bringing back more than 1 item as your code is trying to set the selected item to be the second item.

Statuses = new SelectList(statuses, "Id", "Name", statuses[1].Id);

Remember that Lists a re zero based indexed.

jgarcia
Good catch, but I wasn't getting an OutOfBounds exception. I was guaranteeing I had more than 1 value for the sake of testing.
hometoast
A: 

As expected - it WAS something simple.

I changed the view to look like:

    <label for="Status.Id">Status:</label>
    <%= Html.DropDownList("Status.Id", Model.Statuses)%>
    <%= Html.ValidationMessage("Status.Id", "*")%>

and the controller signature to take an "issue" (can't bind to a selectlist!)

    [AcceptVerbs(HttpVerbs.Post)]
    //public ActionResult Create(IssueFormViewModel issueFormView)
    public ActionResult Create(Issue issueToAdd)
    {

And in my Post-Create action I have an Issue with a Status. Albeit the status is invalid (it only contains the Id). So before commiting the Issue to the db, I set the issueToAdd like this:

    issueToAdd.Status = (from p in GetAllStatuses() 
                         where p.Id == issueToAdd.Status.Id 
                         select p).First();

Edit: And it turns out I didn't even need to fetch a "proper" Status object. It's bound to Id and that's good enough.

hometoast