ModelState.IsValid возвращает false, когда оно должно быть истинным - PullRequest
2 голосов
/ 08 ноября 2010

У меня довольно простая форма MVC 2.Он имеет два раскрывающихся списка: пользователь и роль.Раскрывающийся список сотрудников проходит проверку, а раскрытие роли - нет, независимо от того, что я выбрал.По умолчанию нет «пустой» опции, хотя я планирую ее реализовать, поэтому мне нужно, чтобы проверка работала.Он не проходит проверку как клиента, так и сервера.Я просто не понимаю, почему кто-то работает, а кто-то нет!

Форма:

<% using (Html.BeginForm()) {%>

    <%:Html.ValidationSummary(true) %>
    <%:Html.EditorFor(model => model.User, new { AllEmployees = Model.AllEmployees, RoleList = Model.RoleList })%>

    <p>
        <input type="submit" value="Add New User" />
    </p>

    <% } %>

<% Html.EndForm(); %>

Шаблон редактора:

<tr>
    <td>
        <div class="editor-label">
            <%: Html.LabelFor(model => model.UserId) %>
            <%: Html.RequiredMarkFor(model => model.UserId) %>
        </div>   
    </td>    
    <td>    
    <div class="editor-field">
        <%: Html.DropDownListFor(model => model.UserId, new SelectList(ViewData["AllEmployees"] as IEnumerable, "UserId", "DisplayName", Model.UserId)) %>
        <%: Html.ValidationMessageFor(model => model.UserId>
    </div>    
    </td>       
</tr>     

<tr>
    <td>
        <div class="editor-label">
            <%: Html.LabelFor(model => model.AccessLevel)%>
            <%: Html.RequiredMarkFor(model => model.AccessLevel)%>
        </div>   
    </td>    
    <td>    
        <div class="editor-field">
            <%: Html.DropDownListFor(model => model.AccessLevel, new SelectList(ViewData["RoleList"] as IEnumerable, Model.AccessLevel))%>
            <%: Html.ValidationMessageFor(model => model.AccessLevel)%>
        </div>    
    </td>       
</tr> 

Метаданные:

    [DisplayName("Employee")]
    [Required(ErrorMessage = "Please select an employee.")]
    [StringLength(8, ErrorMessage = "User Id must be less than 8 characters.")]
    [DisplayFormat(ConvertEmptyStringToNull = false,
                            HtmlEncode = true)]
    [DataType(DataType.Text)]
    public object UserId { get; set; }


    // Validation rules for Access Level
    [DisplayName("Role")]
    [Required(ErrorMessage = "Please select the role for this user.")]
    [StringLength(15, ErrorMessage = "Role must be under 15 characters.")]
    [DisplayFormat(ConvertEmptyStringToNull = false,
                            HtmlEncode = true)]
    [DataType(DataType.Text)]
    public object AccessLevel { get; set; }

Действие Get:

    List<String> roles = (from o in txDB.Users
                                      select o.AccessLevel).Distinct().ToList(); 

    var viewModel = new UserViewModel
    {
        User = new User(),
        AllEmployees = empList,
        RoleList = roles
    };
    return View(viewModel);

Действие после публикации:

    [HttpPost]
    [AuthorizeAttribute(Roles="Administrator")]
    public ActionResult Create(User user)
    {
        if(!ModelState.IsValid)
        {
            //ModelState is invalid
            return View(new User());
        }
        try
        {
           //do stuff
        }
    }

Обязательный вспомогательный метод (из Определение разметки для полей [Обязательный] в представлении в ASP.NET MVC 2.0 ):

    public static string RequiredMarkFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
    {
        if(ModelMetadata.FromLambdaExpression(expression, helper.ViewData).IsRequired)
            return "*";
        else
            return string.Empty;
    } 

Ответы [ 2 ]

2 голосов
/ 08 ноября 2010

Post метод должен быть следующим, чтобы получить проверку на стороне сервера ...

[HttpPost]
[AuthorizeAttribute(Roles="Administrator")]
public ActionResult Create(User user)
{
    if(!TryUpdateModel(user))
    {
       // Model is INVALID
       return View(user);
    }
    else
    {
        // ModelState is VALID
        // Do stuff
    }
}

else может быть избыточным в зависимости от того, что вы делаете, но это должно помочь вам.В представлении выше вашего <% using Html.BeginForm() %> вам нужно

<% Html.EnableClientValidation(); %>

Вам также нужно сослаться на скрипты, MicrosoftAjax и MicrosoftMvcValidation, я думаю

1 голос
/ 08 ноября 2010

Прежде всего: у вас есть два тега закрывающей формы

Если вы используете

<% using (Html.BeginForm()) {%>
<% } %>

, вам не нужно использовать это

<% Html.EndForm(); %>

Относительно вашей проблемы проверкивы используете редактор только для своего свойства User, которое является единственным, которое связывается с помощью связывателя модели

<%:Html.EditorFor(model => model.User, new { AllEmployees = Model.AllEmployees, RoleList = Model.RoleList })%>

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

Итак, ваша форма должна измениться в

<% using (Html.BeginForm()) {%>

    <%:Html.ValidationSummary(true) %>
    <table>
        <%:Html.EditorForModel()%>
    </table>
    <p>
        <input type="submit" value="Add New User" />
    </p>
<% } %>

и все готово!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...