TextBoxFor() не генерирует разметку проверки

У меня есть SQL Server 2012, в котором у меня есть таблица AWARD с двумя столбцами TITLE и MONTH. TITLE имеет тип varchar(256) и не может быть NULL. MONTH имеет значение int и может быть NULL.

В VS2012 Ultimate и EF 5.0.0 помощник TextBoxFor в приложении MVC4 не выполняет проверку (data-val="required" and data-val-required="required message") для столбца TITLE выше, но в том же представлении MONTH получает правильную разметку проверки. Дизайнер .edmx действительно показывает, что TITLE не имеет значения Nullable, НО автоматически сгенерированный файл AWARD.cs не имеет атрибута [Required] для столбца TITLE.

Что я могу попробовать?

@model MyProject.Models.AWARD

@{
    ViewBag.Title = "Add Award";
    Layout = "~/Views/Shared/_EditorLayout.cshtml";
}

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Add Award</legend>
        <table>
            <tr>
                <td>
                    @Html.LabelFor(model => model.TITLE)
                </td>
                <td>
                    @Html.TextAreaFor(model => model.TITLE)
                    <br />@Html.ValidationMessageFor(model => model.TITLE)
                </td>
            </tr>
        <tr>
            <td>
                @Html.LabelFor(model => model.MONTH)
            </td>
            <td>@Html.DropDownListFor(model => model.MONTH, new SelectList(MyProject.Models.Helpers.Months, "key","value"), "[Not Selected]")
                <br />@Html.ValidationMessageFor(model => model.MONTH)
            </td>
        </tr>

            <tr>
                <td>
                    <input type="submit" value="Add" />
                </td>
                <td>
                    @Html.ActionLink("Cancel", "Index", null, new { @class = "cancel-button" })</td>
            </tr>
        </table>
    </fieldset>
}

person joym8    schedule 25.01.2013    source источник
comment
Можете ли вы опубликовать свою модель просмотра?   -  person Ant P    schedule 26.01.2013


Ответы (1)


Вы не должны привязывать свои представления непосредственно к объектам сопоставления данных. Вам следует создать классы модели представления для переноса данных, которые вы передаете в представление и из него, а затем заполнять объекты данных из контроллера.

Затем вы можете выполнить необходимую проверку модели представления, не затрагивая созданные вами классы сопоставления.

Модель

public class AwardViewModel
{
    [Required, StringLength(30)]
    public string Title { get; set; }
    ....
}

Просмотреть

@model AwardViewModel

@using (Html.BeginForm()) {
    @Html.EditorFor(m => m.Title)
    @Html.ValidationMessageFor(m => m.Title)
    ...
}

Контроллер

[HttpPost]
public ActionResult Create (AwardViewModel model)
{
    /* Create new AWARD in entity context, populate
       with relevant fields from model and commit. */
}
person Ant P    schedule 25.01.2013
comment
Ant P, это тот же ответ, который я нашел на различных форумах, и, судя по моему небольшому опыту, этот подход имеет свой собственный багаж, например, отсутствующие свойства навигации (реляционной базы данных), если вы не соответствуете той же модели базы данных в своей ViewModel. Я даже согласен с вами, но я хотел бы решить проблему: ПОЧЕМУ TextBoxFor не дает проверки HTML, а DropDownListFor - в той же HTML-форме. - person joym8; 26.01.2013
comment
Кроме того, я знаю, что могу добавить разметку проверки самостоятельно в TextBoxFor и покончить с этим, или добавить атрибут [Required] в файл AWARD.cs под моим деревом .edmx. Но для меня это больше похоже на взлом. - person joym8; 26.01.2013
comment
вставка сюда для справки: stackoverflow.com/questions/3000812/ - person joym8; 26.01.2013
comment
Очень полезная ссылка - пока MS не предложит альтернативный взгляд на создание кода из базы данных: visualstudiogallery.msdn.microsoft.com/ - person joym8; 26.01.2013
comment
Я не уверен, что вы имеете в виду под отсутствующими свойствами навигации - в этом вся суть модели представления. Ваша модель представления — это модель для вашего представления, а не для ваших объектов данных. Вы предоставляете ему любую информацию, необходимую для представления, и это не обязательно ограничивается информацией из одного бизнес-объекта/класса. На самом деле нет никаких сомнений в том, что совместное использование ваших бизнес-сущностей напрямую с вашим представлением является плохой практикой - это приведет вас непосредственно к проблемам, подобным той, что у вас есть здесь. Ваши представления не должны (и, действительно, не должны) знать о вашей модели данных. - person Ant P; 27.01.2013
comment
Ant P ты прав - согласен. Плохой код с моей стороны. Но мой вопрос действительно основан на предположении, что EF все равно, разделяю ли я бизнес-объект с представлением или нет. Это мой выбор. EF должен выполнять свою работу, чтобы предоставлять правильные аннотации Nullable и/или данных. - person joym8; 28.01.2013