Вопрос по asp.net-mvc, asp.net-mvc-3 – Связывание модели не работает

8

У меня есть следующие классы POCO:

public class Location
    {
        public int LocationId { get; set; }
        public string Name { get; set; }
        public string Street { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string ZipCode { get; set; }
        public string Country { get; set; }
        public float? Latitude { get; set; }
        public float? Longitude { get; set; }
        public string PhoneNumber { get; set; }
        public string EmailAddress { get; set; }
        public string Website { get; set; }
        public virtual ICollection<Program> Programs { get; set; }
        public virtual ICollection<PlayerType> PlayerTypes { get; set; }
    }

public class PlayerType
    {
        public int PlayerTypeId { get; set; }
        public string Name { get; set; }
        public int SortOrder { get; set; }
        public bool IsActive { get; set; }
        public virtual ICollection<Location> Locations { get; set; }
    }

И класс View Model

public class LocationViewModel
    {
        public Location Location { get; set; }
        public IList<PlayerType> SelectPlayerTypes { get; set; } 

        public LocationViewModel()
        {
            Location = new Location();
        }

    }

В моей форме создания я определил модель как

@model Locator.Models.LocationViewModel

И есть поля, подобные следующим:

div class="editor-label">
    @Html.LabelFor(model => model.Location.Name)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.Location.Name)
    @Html.ValidationMessageFor(model => model.Location.Name)
</div>

В моем контроллере для обработки POST у меня есть

[HttpPost]
        public ActionResult Create(LocationViewModel location)
        {
            if (ModelState.IsValid) {
                locationRepository.InsertOrUpdate(location.Location);
                locationRepository.Save();
                return RedirectToAction("Index");
            }
            location.SelectPlayerTypes = golferTypeRepository.All.Where(p => p.IsActive).ToList();
            return View(location);
        }

Проблема в том, что у меня есть объект Location, но ни одно из свойств не может быть установлено на значения, введенные в форму.

Я что-то здесь не так делаю?

Спасибо

Я обновил конструктор Create, чтобы он стал общедоступным ActionResult Create (модель LocationViewModel, Location Location), и он работает. Mike
Да, это то, на что я надеялся, что ты попробуешь. О, хорошо, угадайте, что это не проблема. Kirk Woll
Я создал его в Create ActionResult (не в сообщении), и теперь, когда я публикую сообщение, Location имеет значение null. Mike
Когда вы говорите, что ни одно из свойств не должно устанавливать значения, введенные в форму - где и как вы это определяете? user1166147
Я могу быть выключен, но я думаю, что ваша инициализацияLocation в конструкторе скину. Можете ли вы попробовать удалить эту строку (и создать экземпляр свойства вне самой модели)? Kirk Woll

Ваш Ответ

9   ответов
1

Просто чтобы повторить то, что говорил Тод, для подшивки модели нужно «имя». атрибут в элементе HTML для сопоставления свойств. Я делал быструю тестовую форму вручную и использовал только «идентификатор». атрибут для идентификации моих элементов.

Все стало на свои места, когда я добавил «имя». приписывать.

<input type="text" id="Address" name="Address" />
0

Это спасло мой день. Я имел следующее:

public ActionResult Edit(int masterId, ConclusionView conclusion)

ConclusionView имеет свойство с именемConclusion поэтому я чуть не сошел с ума.

1

И еще одна причина: Обычно я использую встроенные редакторы или дисплеи для и никогда не сталкивался с этой проблемой. Однако в этом случае мне потребовался полу-пользовательский контроль. В основном это выпадающий список с множеством атрибутов данных в опциях.

То, что я делал, для моего тега выбора было:

<select name="@Html.IdFor(x => x.SubModel.ID)" id="@Html.IdFor(x => x.SubModel)" class="form-control select-control">

Теперь все отправлялось назад и неопытному глазу казалось, что все должно работать и связываться. Однако помощник IdFor отображает подмодели с подчеркиванием. Связыватель модели не интерпретирует подчеркивания как индикатор иерархии классов. То, что должно их отделять, это точка. Что происходит от NameFor:

<select name="@Html.NameFor(x => x.SubModel.ID)" id="@Html.IdFor(x => x.SubModel)" class="form-control select-control">

NameFor исправил все мои проблемы.

0

Я знаю, что уже слишком поздно комментировать это. Что я сделал, так это добавил конструктор без параметров в ViewModel, и все заработало потрясающе.

0

Если у кого-то еще возникнут проблемы с этим, если вы укажете, что ваш параметр в вашем методе post совпадает с одним из ваших свойств, связыватель моделей по умолчанию также не будет работать.

43

Вот проблема:

[HttpPost]
public ActionResult Create(LocationViewModel location)

Вы видите это? Это имя аргумента вашего действия:location.

Посмотрите на вашу модель представления сейчас, у нее есть свойство с именемLocation:

public Location Location { get; set; }

Это смущает модель связующего. Он больше не знает, нужно ли вам связыватьLocationViewModel или его собственность.

Так что просто переименуйте, чтобы избежать конфликта:

[HttpPost]
public ActionResult Create(LocationViewModel model)
Я не могу перестать смеяться, как это заставило меня чувствовать себя сбитым в течение нескольких минут
Со мной тоже получилось, отличный ответ!
У меня был класс со свойством Model для марки / модели транспортного средства. Конечно, мой переданный параметр былmodel. facepalm
31

Просто чтобы указать еще одну возможную причину: я потратил пару часов на поиск ошибки в моем коде, и причина, по которой механизм связывания не работал в моем случае, заключалась в использовании модели с открытыми полями, а не с открытыми свойствами:

public int CustomerName;

и это должно быть:

public int CustomerName { get; set; }

Я работаю над ASP.NET MVC уже 3 года, и я никогда не сталкивался с этим раньше. Надеюсь, это спасет кого-то от разочарования;)

Error: User Rate Limit Exceededpublic.
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
2

Позвольте мне добавить здесь еще одну причину, по которой связыватель модели не будет работать должным образом.

У меня была модель со свойствомContactPhoneгде-то по пути я решил изменить название этого свойства наPhoneзатем внезапная привязка модели для этого свойства перестала работать, когда я пытался создать новый экземпляр.

Проблема была наCreate действие в моем контроллере. Я использовал стандартные леса Visual Studio, и он создал сигнатуру метода следующим образом:

public ActionResult Create([Bind(Include = "Id,ContactPhone, ...")] Customer customer)
{ ... }

Обратите внимание наBind атрибут, скаффолдер создал поля, используя оригинальное имяContactPhone и поскольку это строка, она не подверглась рефакторингу. Как новое полеPhone не было включено, это значение было проигнорировано связующим звеном модели.

Надеюсь, это сэкономит кому-то время.

Удачи!

4

Также поздно вступать в партию, но после 3 лет работы asp.net mvc я обнаружил, что отключенные входы не публикуются, поэтому связыватель модели, конечно, не может их связать. УвидетьВот:

"Disabled elements in a form will not be submitted".

Лучше использоватьreadonly="readonly" более отключен. УвидетьВот.

Похожие вопросы