2010-11-18 7 views
1

私は最終的に1つのハードルを超え、新しいモデルデータを正常に作成できます。もう一つのキャッチバリデーションがあります。私のモデルデータの多くはスカラー値なので、ほとんどの検証は簡単です。しかし、私がリンクしている多対多の関係があるので、それを検証する方法についてはわかりません。はい、私はそれがずさんなと素人であることを知っている(MVC2/EF4 EntityCollectionの検証はデータアノテーションを使用してどのように行いますか?

​​

そして、私のメソッドを作成します - I 午前アマチュアと学ぼうとは、私は間違いなくエラーがそれにチェックを追加します:私のモデルは(再び)です。私はただの全体像を取得しようとしている表示 - > controller-> validation->持続-に-DB /ショーエラーは)ダウンプロセス:

public ActionResult CreateReview([Bind(prefix = "GameData")]Game newGame, int[] PlatformIDs) 
{ 
    try 
    { 
     foreach(int i in PlatformIDs) 
     { 
      Platform plat = _siteDB.Platforms.Single(p => p.PlatformID == i); 
      newGame.Platforms.Add(plat); 
     } 

     newGame.LastModified = Datetime.Now; 

     _siteDB.Games.AddObject(newGame); 
     _siteDB.SaveChanges(); 

     return RedirectToAction("Index"); 
    } 
    catch 
    { 
     return View(); 
    } 
} 

PlatformIDsの配列は、以下の群によって供給されています私のビュー内のチェックボックス。私のゲームが有効であるためには、少なくとも1つのプラットフォームと関連していなければなりません。データアノテーションでそれをどのように検証するのか、それが可能かどうかは分かりません。どんな助けでも大歓迎です。

答えて

1

あなたの質問を正しく理解していれば、int []にはDBのプラットフォームのIDに関連付けられたintが含まれていてint []に少なくとも1つの有効なPlatformIDが含まれていることを確認してください。

すぐにあなたのロジックに入る前にちょうど簡単なチェックを行うことができます:あなたがしたいと思いますどのような理想的

// If there aren't any IDs in Platform that are in PlatformIDs... 
if (!_siteDB.Platforms.Any(p => PlatformIDs.Contains(p.PlatformID))) 
    Return RedirectToAction("Index"); 
    // And probably tell the user to check a box, if they did, 
    // One of your checkboxes isn't matching up with your PlatformIDs 

は、モデルの検証を確認することができますので、あなたのモデルに[] int型を追加しています。 databasedは通常int []を格納しないので、それをゲームモデルに追加します。おそらく、EFはあなたのModelsフォルダにあなたのDBエンティティを置き、あなたがそれらを見れば、それらが部分クラスであることがわかります。だからあなたのモデルフォルダにこれを追加します。

public partial class Game 
{ 
    public Dictionary<int, bool> SupportedPlatforms { get; set; }// Edited 
} 

// Also add this which you'll see why below 
public partial class Platform 
{ 
    public static bool IsValidPlatformID(int PlatformID) 
    { 
     using (SiteDBEntities _siteDB = new SiteDBEntities()) 
      return _siteDB.Platforms.Any(p => p.PlatformID.Equals(PlatformID)); 
    } 
} 

次にカスタムValidationAttributeクラスを追加します。

public ContainsValidPlatformIDAttribute : ValidationAttribute 
{ 

    public ContainsValidPlatformIDAttribute() { } 

    public override bool IsValid(object value) 
    { 
     Dictionary<int, bool> supportedPlatforms = (Dictionary<int, bool>)value; 
     if (value == null) 
      return true; 
     foreach (int i in values) 
     { 
      if (supportedPlatforms.Values.Any(b => b.Equals(true)))// Edited 
       return false; 
     } 
     return true; 
} 

は今ゲームのクラスでそれをあなたの財産を飾る:

[ContainsValidPlatformID(Error = "You did not select a valid Platform.")] 
public Dictionary<int, bool> SupportedPlatforms { get; set; }// Edited 

(編集後)各プラットフォームのチェックボックスをハードコーディングする代わりに、次のように追加してください。

<%: Html.CheckboxFor(model => model.SupportedPlatforms[0]) %> 
<%: Html.ValidationMessageFor(model => model.SupportedPlatforms[0]) %> 

(編集済み)チェックボックスがモデルに関連付けられているので、コントローラのモデルを検証でき、Actionメソッドからint []引数を削除できます。これはすべて私の頭からこのエディタにコーディングされているので、ここでいくつかのことを微調整する必要があるかもしれませんが、これはビューのモデルで作業するときに向かうべき方向です。

また、Scott GuthrieがブログでMVC Model Validationのトピックについて書いた記事をチェックしてください。うまくいけば、私のサンプルとScottのブログで、あなたは正しい方向に向かうでしょう。

+0

ええ、フォームは少し問題です。私は手動でチェックボックスをハードコーディングしました。そのため、それらはほとんどがまっすぐなHTMLであり、その値はModel.AllPlatforms [i] .PlatformIDでループに設定されています。私はまだプラットフォームにビューが選択されているかどうかを示すためにDBにバックアップされていないbooleanをPlatformに追加する必要があるかどうかについて議論しています。それは強く型付けされたHTMLヘルパーを使用することを可能にし、おそらく長期的にはより簡単に検証を行うでしょう。あなたの考え? –

+0

このようなことは意味がありますか? http:// pastie。org/1311555 –

+0

ちょっとケビン、私の応答を編集しました。私が提供したものは、あなたがすべきことの行に沿ったものだと思います。チェックボックスをモデルに結びつける方法はいろいろありますが、最終的にはそれらをモデルにいくつかの形で結び付けたいと思っています。それが意味をなさないかどうか私に教えてください。 – nwayve

関連する問題