Пользовательская модель представления с MVC 2 сильно типизированных HTML-помощников возвращают нулевой объект при создании? - PullRequest
4 голосов
/ 22 марта 2010

У меня возникла проблема при попытке создать объект с пользовательским представлением, смоделированным формой создания. Ниже представлена ​​моя пользовательская модель представления для формы создания категории.

public class CategoryFormViewModel
{
    public CategoryFormViewModel(Category category, string actionTitle)
    {
        Category = category;
        ActionTitle = actionTitle;
    }

    public Category Category { get; private set; }
    public string ActionTitle { get; private set; }
}

и это мой пользовательский элемент управления, где пользовательский интерфейс

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<CategoryFormViewModel>" %>

        <h2>
            <span><%= Html.Encode(Model.ActionTitle) %></span>
        </h2>
        <%=Html.ValidationSummary() %>
        <% using (Html.BeginForm()) {%>
        <p>
            <span class="bold block">Başlık:</span>
            <%=Html.TextBoxFor(model => Model.Category.Title, new { @class = "width80 txt-base" })%>
        </p>
        <p>
            <span class="bold block">Sıra Numarası:</span>
            <%=Html.TextBoxFor(model => Model.Category.OrderNo, new { @class = "width10 txt-base" })%>
        </p>        
        <p>
            <input type="submit" class="btn-admin cursorPointer" value="Save" />
        </p>
        <% } %>

Когда я нажимаю кнопку «Сохранить», она не связывает категорию для меня, потому что я использую пользовательскую модель представления и строго типизированные html-помощники, подобные этой

<%=Html.TextBoxFor(model => Model.Category.OrderNo) %>

Мой источник HTML выглядит так

<form action="/Admin/Categories/Create" method="post">
        <p>
            <span class="bold block">Başlık:</span>
            <input class="width80 txt-base" id="Category_Title" name="Category.Title" type="text" value="" />
        </p>
        <p>
            <span class="bold block">Sıra Numarası:</span>
            <input class="width10 txt-base" id="Category_OrderNo" name="Category.OrderNo" type="text" value="" />
        </p>        
        <p>
            <input type="submit" class="btn-admin cursorPointer" value="Kaydet" />
        </p>
        </form>

Как я могу это исправить?

Ответы [ 3 ]

8 голосов
/ 23 марта 2010

Ваша модель представления нуждается в конструкторе по умолчанию без параметров, и вам нужны открытые методы set для каждого из свойств. Связыватель модели по умолчанию использует открытые сеттеры для заполнения объекта.


Связыватель модели по умолчанию имеет несколько следующих правил. Он выбирает данные для привязки в следующем порядке:

  1. Параметры формы из поста
  2. Данные маршрута URL, определенные вашими определениями маршрута в global.asax.cs
  3. Параметры строки запроса

Связыватель модели по умолчанию затем использует несколько стратегий для привязки к моделям / параметрам в ваших методах действия:

  1. Точное совпадение имен
  2. Соответствует prefix.name, где prefix - родительский класс, а name - подкласс / свойство
  3. Имя без префикса (если нет коллизий, вам не нужно беспокоиться о предоставлении префикса)

Вы можете переопределить поведение с помощью нескольких опций из атрибута Bind. К ним относятся:

  • [Bind (Prefix = "someprefix")] - принудительно отображает определенный родительский класс, определенный префиксом.
  • [Bind (Include = "val1, val2")] - белый список имен для привязки к
  • [Bind (Exclude = "val1, val2")] - имена, исключаемые из поведения по умолчанию
2 голосов
/ 16 октября 2010

Создайте конструктор по умолчанию для вашей модели представления и инициализируйте категорию там

public CategoryFormViewModel() 
{ 
    Category = new Category()
}

А на вашем контроллере действие получит модель просмотра

public ActionResult ActionName(CategoryFormViewModel model)
{
    //here you can access model.Category.Title
}
2 голосов
/ 23 марта 2010

Вы можете использовать шаблоны редактора. Поместите свой элемент управления ascx в ~/Views/Shared/EditorTemplates/SomeControl.ascx. Затем внутри вашего основного представления (aspx-страницы) включите шаблон примерно так (при условии, что ваше представление строго набрано CategoryFormViewModel):

<%= Html.EditorForModel("SomeControl") %>

вместо

<% Html.RenderPartial("SomeControl", Model) %>
...