MVC 3 Selectlist/DropDownList не обновляет мою модель

Я надеюсь, что кто-то может помочь с этим. У меня есть три класса моделей:

public class Provider
{
    public Guid ProviderId { get; set; }
    public string Name { get; set; }

    public Guid LocationId { get; set; }

    public virtual Location Location { get; set; }
}

public class Location
{
    public Guid LocationId { get; set; }
    public string NameOrCode { get; set; }
    public string Description { get; set; }
    public string StreetNumber { get; set; }
    public string StreetAddress1 { get; set; }
    public string StreetAddress2 { get; set; }
    public string City { get; set; }

    public int? StateId { get; set; }

    public string Zip { get; set; }
    public string ContactPhone { get; set; }

    public virtual State State { get; set; }
}

public class State
{
    public int StateId { get; set; }
    public string Name { get; set; }
    public string Abbreviation { get; set; }
}

Как видите, у Provider есть Location (отдельный класс для повторного использования в другом месте), а у Location есть состояние (которое равно null, пока оно не выбрано).

Мой контроллер выглядит так для моих методов Create:

public class ProviderController : BaseController
{
    private SetupContext db = new SetupContext();

    // other CRUD methods ...

    //
    // GET: /Provider/Create

    public ActionResult Create()
    {
        Location location = new Location() 
        { 
            LocationId = Guid.NewGuid(), 
            NameOrCode = Resources.BillingLocation,
            Description = Resources.BillingLocationDescription
        };
        Provider provider = new Provider()
        {
            ProviderId = Guid.NewGuid(),
            LocationId = location.LocationId,
            Location = location
        };
        ViewBag.StateId = new SelectList(db.States, "StateId", "Name", provider.Location.StateId);

        return View(provider);
    } 

    //
    // POST: /Provider/Create

    [HttpPost]
    public ActionResult Create(Provider provider)
    {
        if (ModelState.IsValid)
        {
            db.Locations.Add(provider.Location);
            db.Providers.Add(provider);
            db.SaveChanges();

            return RedirectToAction("Index");  
        }

        ViewBag.StateId = new SelectList(db.States, "StateId", "Name", provider.Location.StateId);
        return View(provider);
    }

    // other CRUD methods ... 
}

Наконец, мой вид выглядит так:

<div class="editor-label">
    @Html.LabelFor(model => model.Location.StateId, @Resources.Location_State_Display_Name)
</div>
<div class="editor-field">
    @Html.DropDownList("StateId", @Resources.ChooseFromSelectPrompt)
    @Html.ValidationMessageFor(model => model.Location.StateId)
</div>

Моя проблема в том, что состояние, которое пользователь выбирает в DropDownList, никогда не устанавливается в моей модели при создании POST. У меня есть аналогичный код в моем представлении редактирования, и состояние заполняется правильно в этом представлении (то есть состояние, связанное с существующим Provider.Location, показывает выбранное в DropDownList для редактирования пользователем при желании), но как в Create, так и в Представления редактирования, сделанные пользователем, никогда не регистрируются в моей модели (в частности, Provider.Location.StateId), поступающей из POST.

Глядя на созданный HTML, я вижу это:

<div class="editor-label">
    <label for="Location_StateId">State/Territory</label>
</div>
<div class="editor-field">
    <select id="StateId" name="StateId"><option value="">[Choose]</option>
        <option value="1">Alabama</option>
        <option value="2">Alaska</option>
        <!-- more options ... -->
    </select>
    <span class="field-validation-valid" data-valmsg-for="Location.StateId" data-valmsg-replace="true"></span>
</div>

Я подозреваю, что мне нужно каким-то образом передать отношение Location.StateId, а не просто StateId, как я вижу выше, но я не могу понять правильный синтаксис для этого. Я попытался изменить динамическое свойство ViewBag на Location_StateId следующим образом:

ViewBag.Location_StateId = new SelectList(db.States, "StateId", "Name", provider.Location.StateId);

И DropDownList в моем представлении выглядит так:

@Html.DropDownList("Location_StateId", @Resources.ChooseFromSelectPrompt)

Тогда я подумал, что, возможно, эта запись сработает, потому что метка рядом с моим DropDownList отображалась как:

<div class="editor-label">
    <label for="Location_StateId">State/Territory</label>
</div>

Эта попытка не сработала. Можете ли вы мне помочь?

Заранее спасибо.


person jlavallet    schedule 28.09.2011    source источник


Ответы (1)


@Html.DropDownList("Location.StateId", @Resources.ChooseFromSelectPrompt)

Также следующая строка не делает ничего полезного:

ViewBag.StateId = new SelectList(db.States, "StateId", "Name", provider.Location.StateId);

Вы назначаете SelectList чему-то, что должно быть скалярным свойством. Вероятно, вы хотели передать коллекцию как ViewBag:

ViewBag.States = new SelectList(db.States, "StateId", "Name", provider.Location.StateId);

а затем в представлении:

@Html.DropDownList("Location.StateId", (SelectList)ViewBag.States)
person Darin Dimitrov    schedule 28.09.2011
comment
Большое тебе спасибо! Теперь я намного лучше разбираюсь в соответствующих частях API, и сейчас выбираются состояния. - person jlavallet; 29.09.2011