Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET MVC-使用视图模型时的客户端验证_C#_Jquery_Asp.net Mvc_Validation - Fatal编程技术网

C# ASP.NET MVC-使用视图模型时的客户端验证

C# ASP.NET MVC-使用视图模型时的客户端验证,c#,jquery,asp.net-mvc,validation,C#,Jquery,Asp.net Mvc,Validation,我有一个非常简单的ASP.NETMVC网站,用户可以在其中浏览产品并进行预订。要放置它,他们必须指定名称和电子邮件地址。控制器如下所示: [HttpGet] public ActionResult Product(string id) { return View(new ProductViewModel(id)); } [HttpPost] public ActionResult Product(PreOrderProductCommand command) { if (Mod

我有一个非常简单的ASP.NETMVC网站,用户可以在其中浏览产品并进行预订。要放置它,他们必须指定名称和电子邮件地址。控制器如下所示:

[HttpGet]
public ActionResult Product(string id)
{
    return View(new ProductViewModel(id));
}

[HttpPost]
public ActionResult Product(PreOrderProductCommand command)
{
    if (ModelState.IsValid)
    {
        command.Process();
        return View("ThankYou");
    }
    else
        return Product(command.Id);
}
@Html.ValidationMessageFor(model => model.Email)
ProductViewModel
包含各种产品信息(名称、说明、价格等),
PreOrderProductCommand
仅包含3个
字符串
属性:
Id
名称
电子邮件
。
现在,我想使用
jquery.validate启用
Name
Email
的客户端验证,但不知道如何实现它。网络上的所有教程都说我必须使用如下代码:

[HttpGet]
public ActionResult Product(string id)
{
    return View(new ProductViewModel(id));
}

[HttpPost]
public ActionResult Product(PreOrderProductCommand command)
{
    if (ModelState.IsValid)
    {
        command.Process();
        return View("ThankYou");
    }
    else
        return Product(command.Id);
}
@Html.ValidationMessageFor(model => model.Email)
但问题是我的视图将ProductViewModel作为一个模型,而这个类没有属性
Email
。此属性及其验证逻辑位于
PreOrderProductCommand


在这种情况下,实现客户端验证的正确方法是什么?我缺少什么?

否,对于客户端验证,您应该将
电子邮件
属性添加到您的
产品视图模型中

发生这种情况的原因是HtmlHelpers根据ViewModel属性上方的属性在输入中创建
数据验证
属性,然后jquery。验证检查此属性

服务器端验证之所以有效,是因为它使用了不同的机制。在将请求属性绑定到您的模型(在您的示例中是
PreOrderProductCommand
model)之后,它会检查服务器上的验证属性。绑定是根据属性的名称进行的,所以如果您有正确的名称,一切都应该是好的


唯一的其他方法是使用所需的验证属性手动创建标记。(在您的视图中,我指的是纯html),但我不推荐使用。

您需要将电子邮件属性添加到ProductViewModel中。具有以下属性:

[DisplayName("Email")]
[Required(ErrorMessage = "Please enter email")]
public string email { get; set; }
然后将此模型传递到HttpPost控制器中

并从内部填充命令类,即

[HttpPost]
public ActionResult Product(ProductViewModel model)
{

PreOrderProductCommand command = new PreOrderProductCommand();

command.Id = model.id;    
command.Email = model.email;

if (ModelState.IsValid)
{
    command.Process();
    return View("ThankYou");
}
else
    return Product(command.Id);
}

如果我将
Email
添加到
ProductViewModel
中,我必须复制
PreOrderProductCommand
中的所有验证属性,最终在两个不同的类中得到两组相同的验证规则。这似乎很不方便。@holdenmcgrohen您可以定义
abstract
类并从中继承命令和视图模型。但我认为这不值得。不幸的是,您无法从
接口
继承属性。我认为有时候代码中有一些重复是可以的。您可以考虑的另一件事是,在view和post controller上始终具有相同的类(现在您有两个不同的Calase),并且可能有某种映射器。这将起作用,但我正在尝试将视图模型(包含产品信息)与用户输入分开。这两件事在逻辑上非常不同,把它们放在一个对象中是没有意义的。我希望有一种方法可以将它们分开,让客户端验证工作。@holdenmcgrohen,viemodel应该保存视图中的任何内容,如果需要,可以保留用户详细信息,然后可以在控制器中使用第二个类,请参见上面的编辑。我不确定我是否喜欢这样将数据从模型复制到命令:
command.Email=model.Email
。如果您只需要复制两个属性就可以了,但是假设您有20个属性。我正试图找出一种干净的方法,将视图模型(我向用户展示的)与域逻辑(我对用户输入所做的)分开,但这似乎比我想象的要难。