我正在使用一个viewmodel,为某些属性指定了必需的字段验证。我能够使用“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呈现为label而httppost没有该值。
答案 0 :(得分:1)
您可以为此“只读”视图使用具有不同验证要求的其他视图模型。或者您可以在控制器中使用ModelState.Remove()方法来消除您不想验证的属性的错误。 IMO单独的视图模型方法更好。
看到你的代码后编辑
添加隐藏
@Html.DisplayFor(o => o.Name)
@Html.HiddenFor(o => o.Name)
那会将数据传回给帖子上的控制器并导致ModelState.IsValid == true
答案 1 :(得分:1)
这是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属性应用于数据字段。这会强制为字段提供值,即使数据库模式不需要此约束。
答案 2 :(得分:-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; }