2009-08-14 10 views
2

私は2つのフィールドと1つのlinq2sqlエンティティを持つカスタムビューモデルを持っています。すべてのフィールドが無効であっても、linq2sqlクラスのフィールドのみがエラーとして視覚的に示され、viewmodelのフィールドは正常に表示されます。しかし、すべての無効なフィールドについてエラーメッセージが表示されます。カスタムViewModelクラス - プレフィックスが指定されていない限り、すべてのフィールドが無効とマークされているわけではありません。

私のカスタムの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クラスは、検証のために添付たmetadataType属性を持つlinq2sqlエンティティです。

[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; } 
} 

2つのオーバーロードを伴うリポジトリには、AddBookメソッドがあります。一つはのviewmodelを取り、1は、ブックタイプ取る:コントローラにアクションを作成し

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); 
    } 
} 

を次のようになります。

[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 & Field2は無効とマークされていません。フィールドに追加されたCSSクラスはなく、視覚エラー表示のためにスパンタグは生成されません。

Screenshot http://img22.imageshack.us/img22/324/26677634.jpg

しかし、私は何も

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

とViewModelにフィールドをpefixし、それに応じてビューを変更した場合、その後、すべてが正常に動作します:

<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

長い記事は問題ありません...詳細は明確で必要でした。アップアップされました! –

答えて

1

限り、このポストを作るため申し訳ありません

は..私はこの問題は、あなたの変数名とクラス名が同一であるかもしれないと思います。あなたのViewModelでおそらく

は、何かのように通じリファクタリングのビットを必要とします

public Book BookInstance { get; set; } 

の名前を変更し、私はそれがあなたの問題の原因だと思います。

優しさ、

ダン

+0

プロパティ名を変更しても差異はありません – Zuhaib

関連する問題