-1

我正在使用为某些属性指定了必填字段验证的视图模型。我能够使用“displayfor”创建相同模型的只读版本。在页面中,除了这个只读视图之外,还有其他控件以及提交。现在,当我单击“提交”时,它正在得到验证并且 ModelState 无效。如果我们仅将模型用于显示,如何删除验证。

视图模型

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" />
}

Model.State 无效,因为 name 呈现为标签,而 httppost 没有该值。

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确实有验证,它们几乎可以互换使用。

  • 元数据类型

MetadataTypeAttribute 属性使您能够将类与数据模型分部类相关联。在这个关联的类中,您提供了数据模型中没有的附加元数据信息。

例如,在关联的类中,您可以将RequiredAttribute 属性应用于数据字段。即使数据库模式不需要此约束,这也会强制为字段提供值。

于 2012-09-13T20:13:15.337 回答
1

您可以为此“只读”视图使用具有不同验证要求的不同视图模型。或者,您可以在控制器中使用 ModelState.Remove() 方法来消除您不想验证的属性的错误。IMO 单独的视图模型方法更好。

看到你的代码后编辑

添加一个隐藏的

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

在回发上:

ViewData.ValidateGroup(model, "my validation group name");
if (ModelState.IsValid)
{
    ...
}

在视图模型上:

[Required]
[DisplayName("Name")]
[ValidationGroup("my validation group name")]
public string Name { get; set; }
于 2012-09-13T20:13:55.870 回答