これが最善のアプローチだと言っているわけではありませんが、同様のことをしなければならなかったので、検証グループを設定しました。検証グループを定義する各モデルプロパティに配置する属性を作成しました。次に、ポストバックで、ViewDataDictionaryの拡張メソッドを呼び出し、検証を実行する検証グループに渡しました。これにより、他のすべてのグループの検証メッセージが削除されます。次にいくつかのサンプルコードを示します。
属性:
/// <summary>
/// Attribute that assigns the property on a model to a given
/// validation group. By using the ValidationGroupExtension
/// and calling ValidateGroup on the ViewData validation errors
/// for properties that are not included in the validation group
/// will be removed.
/// </summary>
public class ValidationGroup : Attribute
{
/// <summary>
/// The unique name of the group.
/// </summary>
public String Group { get; set; }
public ValidationGroup(String group)
{
this.Group = group;
}
}
拡張機能:
/// <summary>
/// Used in conjunction with the ValidationGroup attribute to
/// specify which fields in a model should be validated. The
/// ValidateGroup extension should be called on ViewData before
/// checking whether the model is valid or not.
/// </summary>
public static class ValidationGroupExtension
{
/// <summary>
/// Remove all validation errors that are assocaited with
/// properties that do not have the ValidationGroup attribute
/// set with the specified group name.
///
/// This only handles flat models.
/// </summary>
/// <param name="viewData">View Data</param>
/// <param name="model">Data model returned</param>
/// <param name="group">Name of the validation group</param>
/// <returns></returns>
public static ViewDataDictionary ValidateGroup(this ViewDataDictionary viewData, Object model, String group)
{
//get all properties that have the validation group attribut set for the given group
var properties = model.GetType().GetProperties()
.Where(x => x.GetCustomAttributes(typeof(ValidationGroup), false)
.Where(a => ((ValidationGroup)a).Group == group).Count() > 0)
.Select(x => x.Name);
//find all properties that don't match these properties
var matchingProperties = viewData.ModelState.Where(x => !properties.Contains(x.Key)).ToList();
//remove any property that isn't in the gorup
foreach (var matchingProperty in matchingProperties)
{
viewData.ModelState.Remove(matchingProperty.Key);
}
return viewData;
}
}
PostBackについて:
ViewData.ValidateGroup(model, "my validation group name");
if (ModelState.IsValid)
{
...
}
ViewModelの場合:
[Required]
[DisplayName("Name")]
[ValidationGroup("my validation group name")]
public string Name { get; set; }