编辑的答案
重新阅读您的问题后,听起来您只是想知道一个值是否被选中。如果是这样,那么只需在Guid
属性上应用RequiredAttribute
并在模型上使其可为空。
public class GuidModel
{
[Required]
public Guid? Guid { get; set; }
public IEnumerable<Guid> Guids { get; set; }
}
在强类型视图中(使用@model GuidModel
)
@Html.ValidationMessageFor(m => m.Guid)
@Html.DropDownListFor(
m => m.Guid,
Model.Guids.Select(g => new SelectListItem {Text = g.ToString(), Value = g.ToString()}),
"-- Select Guid --")
为客户端验证添加JavaScript脚本引用以进行客户端验证。
控制器如下:
public class GuidsController : Controller
{
public GuidRepository GuidRepo { get; private set; }
public GuidsController(GuidRepository guidRepo)
{
GuidRepo = guidRepo;
}
[HttpGet]
public ActionResult Edit(int id)
{
var guid = GuidRepo.GetForId(id);
var guids - GuidRepo.All();
return View(new GuidModel { Guid = guid, Guids = guids });
}
[HttpPost]
public ActionResult Edit(GuidModel model)
{
if (!ModelState.IsValid)
{
model.Guids = GuidRepo.All();
return View(model);
}
return RedirectToAction("Edit");
}
}
这将确保对于模型绑定的
GuidModel
,
Guid
属性是必需的。
原始回答
我认为没有现成的数据注释验证属性能够实现这一点。我写了
一篇关于如何实现这个目标的博客文章; 这篇文章使用了一个IoC容器,但如果您想让它工作,可以采取硬编码的依赖项。
像这样:
public class ValidGuidAttribute : ValidationAttribute
{
private const string DefaultErrorMessage = "'{0}' does not contain a valid guid";
public ValidGuidAttribute() : base(DefaultErrorMessage)
{
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var input = Convert.ToString(value, CultureInfo.CurrentCulture);
if (string.IsNullOrWhiteSpace(input))
{
return null;
}
var guids = new GuidRepository().AllGuids();
Guid guid;
if (!Guid.TryParse(input, out guid))
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
return guids.Any(g => g == guid) ?
new ValidationResult(FormatErrorMessage(validationContext.DisplayName)) : null;
}
}
然后在您发送到控制器操作的模型上
public class GuidModel
{
[ValidGuid]
public Guid guid { get; set; }
}
这提供了服务器端验证。您也可以编写客户端验证来实现此目的,可能使用
RemoteAttribute
,但在这种情况下,我认为没有太多价值,因为唯一会看到此客户端验证的人是在 DOM 中更改值的人;对于普通用户没有任何好处。
int?
。任何Nullable<>
对象的默认值都是null,因此null不是有效值,但0是。但是你正确指出我的示例表明了相反的情况。我会解决这个问题。为了让你所描述的功能起作用(允许null但不允许0),你最好使用类似于[Range(1, int.MaxValue)] int? i {get;set;}
这样的代码。 - Nick Albrecht