Пользовательский класс ViewModel - Не все поля помечены как недействительные, если не указан префикс

2

У меня есть настраиваемая модель просмотра, внутри которой у меня есть два поля и один объект linq2sql. Все поля имеют атрибуты проверки. Даже если все поля недействительны, только поля в классе linq2sql визуально отображаются для ошибки, а поля в режиме просмотра отображаются нормально. Но сообщения об ошибках отображаются для всех недопустимых полей.

My Custom ViewModel выглядит так:

public class BooksViewModel
{
    public SelectList BookCategories { get; set; }

    public Book Book { get; set; }

    [Required(ErrorMessage="Field1 is required")]
    [StringLength(10)]
    public string Field1 { get; set; }

    [Required(ErrorMessage = "Field2 question is required")]
    [StringLength(100)]
    public string Field2 { get; set; }
}

Класс Book - это объект linq2sql, который имеет атрибут metadatatype, прикрепленный для проверки.

[MetadataType(typeof(BookMetadata))]
public partial class Book
{
}
public class BookMetadata
{
    [Required(ErrorMessage="Choose a category")]
    public int CategoryID { get; set; }

    [Required(ErrorMessage = "Title is required")]
    [StringLength(100)]
    public string Title { get; set; }

    [Required(ErrorMessage = "Published date is required")]
    [DataType(DataType.Date, ErrorMessage="Enter a valid date")]
    public DateTime PublishedDate { get; set; }

    [Required(ErrorMessage = "Author is required")]
    [StringLength(50)]
    public string Author { get; set; }
}

В репозитории есть метод AddBook с двумя перегрузками. Один принимает viewmodel и один берет тип книги:

public void AddBook(Book book)
{
    var errors = DataAnnotationsValidationRunner.GetErrors(book);

    if (errors.Any()) {
        throw new RulesException(errors);
    }

    _db.Books.InsertOnSubmit(book);
    _db.SubmitChanges();
}

public void AddBook(BooksViewModel model)
{
    var errors = DataAnnotationsValidationRunner.GetErrors(model);

    if (errors.Any()) {
        throw new RulesException(errors);
    }
}

Действие Create в контроллере выглядит следующим образом:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Exclude = "Book.ID")]BooksViewModel booksViewModel)
{
    try {
        // Validate Book
        _repository.AddBook(booksViewModel.Book);
    } catch(RulesException ex) {
        ex.AddModelStateErrors(ModelState, "Book");
    }

    try {
        // Validate other fields in the view model
        _repository.AddBook(booksViewModel);
    } catch (RulesException ex) {
        ex.AddModelStateErrors(ModelState, "");
    }

    if (ModelState.IsValid) {
        return RedirectToAction("Index");
    } else {
        booksViewModel.BookCategories = new SelectList(_repository.GetAllCategories().AsEnumerable(), "ID", "CategoryName", booksViewModel.Book.CategoryID);
        return (ActionResult)View(booksViewModel);
    }
}

Я использую xVal для создания правил проверки на стороне клиента. Мое создание выглядит следующим образом:

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

    <fieldset>
        <legend>Fields</legend>
        <p>
            <label for="Book.CategoryID">CategoryID:</label>
            <%= Html.DropDownList("Book.CategoryID", Model.BookCategories, "Select")%>
            <%= Html.ValidationMessage("Book.CategoryID", "*")%>
        </p>
        <p>
            <label for="Book.Title">Title:</label>
            <%= Html.TextBox("Book.Title")%>
            <%= Html.ValidationMessage("Book.Title", "*")%>
        </p>
        <p>
            <label for="Book.PublishedDate">PublishedDate:</label>
            <%= Html.TextBox("Book.PublishedDate")%>
            <%= Html.ValidationMessage("Book.PublishedDate", "*")%>
        </p>
        <p>
            <label for="Book.Author">Author:</label>
            <%= Html.TextBox("Book.Author")%>
            <%= Html.ValidationMessage("Book.Author", "*")%>
        </p>
        <p>
            <label for="Field1">Field1:</label>
            <%= Html.TextBox("Field1")%>
            <%= Html.ValidationMessage("Field1", "*")%>
        </p>
        <p>
            <label for="Field2">Field2:</label>
            <%= Html.TextBox("Field2")%>
            <%= Html.ValidationMessage("Field2", "*")%>
        </p>
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>

<% } %>

<div>
    <%=Html.ActionLink("Back to List", "Index") %>
</div>
<%= Html.ClientSideValidation<BooksViewModel>() %>
<%= Html.ClientSideValidation<Book>("Book") %>

проверка на стороне клиента работает нормально.. но если я отключу javascript, а затем отправьте сообщение об ошибке формы, будут отображаться для всех полей, но поля 1 и 2 не будут отмечены как недопустимые. поля и теги диапазона не отображаются для визуальной индикации ошибок.

Снимок экрана http://img22.imageshack.us/img22/324/26677634.jpg

Но если я очищу поля ViewModel чем угодно

public ActionResult Create([Bind(Prefix = "VM", Exclude = "Book.ID")]BooksViewModel booksViewModel)

И измените представление соответственно, тогда все будет хорошо работать:

<p>
    <label for="VM.Book.Title">Title:</label>
    <%= Html.TextBox("VM.Book.Title")%>
    <%= Html.ValidationMessage("VM.Book.Title", "*")%>
</p>

<p>
    <label for="VM.Field1">Field1:</label>
    <%= Html.TextBox("VM.Field1")%>
    <%= Html.ValidationMessage("VM.Field1", "*")%>
</p>

<%= Html.ClientSideValidation<BooksViewModel>("VM") %>
<%= Html.ClientSideValidation<Book>("Book") %>

Что я здесь делаю неправильно?

Извините за то, что вы так долго писали..

  • 0
    Длинный пост не проблема ... информация была ясна и нужна. Upvoted!
Теги:
asp.net-mvc
data-annotations
viewmodel
xval

1 ответ

1

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

Возможно, в вашем ViewModel переименуйте что-то вроде

public Book BookInstance { get; set; }

Для этого потребуется немного рефакторинга, но я думаю, что это причина вашей проблемы.

Доброта,

Dan

  • 0
    Никакое изменение имени свойства не имеет никакого значения

Ещё вопросы

Сообщество Overcoder
Наверх
Меню