我有两个类我正在使用它作为两个不同视图的模型。您可以看到第二个类包含第一个类的实例。第一个包含远程验证属性。
[MetadataType( typeof( ExceptionLogModel.EmailRecipientMetadata ) )]
public class EmailRecipientViewModel
{
public int EmailRecipientID { get; set; }
[Remote( "ValidateEmailRecipientNameUniqueness", "EmailRecipient", ErrorMessage = "Name is not unique." )]
public string Name { get; set; }
[Remote( "ValidateEmailRecipientEmailUniqueness", "EmailRecipient", ErrorMessage = "Email is not unique." )]
public string Email { get; set; }
}
public class EmailRecipientChoices
{
public List<EmailRecipient> UnselectedEmailRecipients { get; set; }
public List<EmailRecipient> SelectedEmailRecipients { get; set; }
public EmailRecipientViewModel EmailRecipient { get; set; }
}
当这些验证在浏览器中触发时,根据视图使用的类,会产生两个不同的请求。您可以看到查询字符串参数名称不同:
http://localhost:55327/EmailRecipient/ValidateEmailRecipientNameUniqueness?Name=sdhsdgh
http://localhost:55327/EmailRecipient/ValidateEmailRecipientNameUniqueness?EmailRecipient.Name=sdhsdgh
以下是我的操作方法的当前版本,该版本不适用于第二个网址:
public JsonResult ValidateEmailRecipientNameUniqueness( string name )
{
var isValid = !_emailRecipientRepo.NameExists( name );
return Json( isValid, JsonRequestBehavior.AllowGet );
}
使用第二个URL时,name参数将为null。我已经读过我应该能够为该参数添加一个Bind属性并添加一个前缀,但这也不起作用。我甚至尝试将前缀设置为EmailRecipient.
以防万一它需要点。为了以防万一,我还在名字中用大写N试了一下。不行。添加它也会破坏其他URL!
public JsonResult ValidateEmailRecipientNameUniqueness( [Bind( Prefix = "EmailRecipient")] string name )
可能的解决方案
我可以让方法获取EmailRecipientViewModel的实例并为其创建一个IModelBinder,在其中我可以查找命名约定并将其分配给实例。这似乎比应该做的更多。
我可以使用@Html.EditorFor()
的重载并告诉它对htmlFieldName使用“Name”,并使用@Html.ValidationMessage( "Name" )
而不是ValidationMessageFor
。唯一的缺点是潜在的命名冲突,但这并不是什么大不了的事。我只需要为所使用的类的所有实例使用唯一的名称。 更新:实际上,如果我这样做,因为我更改了名称,因此在发布表单时会出现问题。这不好。
...
我只是发现我可以让方法不带参数,并手动访问查询字符串。这是一个非常简单的解决方案,但我没有得到很好的参数。
string name = Request.QueryString[ "Name" ] ?? Request.QueryString[ "EmailRecipient.Name" ];
这很容易,我可能只是想用它。但是,由于我已经打开了这个问题,我会问,是否有更优雅的解决方案?
答案 0 :(得分:3)
嗯,我知道这已经晚了但是有一个更优雅的解决方案:
public JsonResult ValidateEmailRecipientNameUniqueness (EmailRecipient recipient)
{
string name = recipient.Name;
var isValid = !_emailRecipientRepo.NameExists(name);
return Json(isValid, JsonRequestBehavior.AllowGet);
}
换句话说,使用模型本身。它将正确绑定name
属性,您只需要此值。
答案 1 :(得分:1)
如果不滚动自己的验证或模型绑定器,就没有一种干净的方法可以做到这一点。可以把它想象成模型绑定,模型绑定器需要知道输入内容的名称,远程验证也是如此。您可以采取的一种方法是在控制器中创建两个单独的远程验证方法,最终调用一个实际执行所有验证工作的方法。