-1

一部のプロパティに必須のフィールド検証が指定されたビューモデルを使用しています。「displayfor」を使用して、同じモデルの読み取り専用バージョンを作成することができました。ページには、この読み取り専用ビューに加えて、送信に加えて他のコントロールもあります。ここで、「送信」をクリックすると、検証され、ModelStateが無効になります。モデルを表示のみに使用する場合の検証を削除する方法。

ViewModel

public class CustomerVM
{
 [Required]
 public string Name {get;set;}
}

意見

@using (Html.BeginForm("CreateCustomer, "Customer", FormMethod.Post))
{   
 @Html.DisplayFor(o => o.Name)

 @..other input controls.@

 <input id="btnSave" type="submit" value="Save" />
}

名前がラベルとしてレンダリングされ、httppostにその値がないため、Model.Stateは無効です。

4

3 に答える 3

2

ここでMetadataTypeAttributeが役に立ちます。

public class MyModel
{
  public string Name { get; set; }
}

public interface IMyModelValidation
{
  [Required]
  public string Name { get; set; }
}

[MetadataType(typeof(IMyModelValiation))]
public class MyModelValidation : MyModel { }

現在MyModel、検証はなく、検証もありMyModelValidation、ほとんど互換的に使用できます。

  • MetadataType

MetadataTypeAttribute属性を使用すると、クラスをデータモデルの部分クラスに関連付けることができます。この関連付けられたクラスでは、データモデルにない追加のメタデータ情報を提供します。

たとえば、関連付けられたクラスで、RequiredAttribute属性をデータフィールドに適用できます。これにより、データベーススキーマでこの制約が必要ない場合でも、フィールドに値が提供されるようになります。

于 2012-09-13T20:13:15.337 に答える
1

この「読み取り専用」ビューには、検証要件が異なる別のビュー モデルを使用できます。または、コントローラーで ModelState.Remove() メソッドを使用して、検証したくないプロパティに対するエラーを取り除くこともできます。IMO 個別のビュー モデル アプローチの方が優れています。

コードを見た後に編集する

hiddenfor を追加する

@Html.DisplayFor(o => o.Name)
@Html.HiddenFor(o => o.Name)

これにより、ポストのコントローラーにデータが返され、ModelState.IsValid == true になります。

于 2012-09-13T19:55:48.603 に答える
-1

これが最善のアプローチだと言っているわけではありませんが、同様のことをしなければならなかったので、検証グループを設定しました。検証グループを定義する各モデルプロパティに配置する属性を作成しました。次に、ポストバックで、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; }
于 2012-09-13T20:13:55.870 に答える