2011-04-27 50 views
3

想象这样的情况:远程验证似乎马车

的SetUp

在默认的MVC3项目,在AccountModels.cs

public class GlobalAccount 
{ 
    public GlobalAccount() 
    { 
     this.LogOn = new LogOnModel(); 
     this.Register = new RegisterModel(); 
    } 

    public LogOnModel LogOn { get; set; } 
    public RegisterModel Register { get; set; } 
} 

创建一个新的复杂类型在RegisterModel变化UserName到:

[Required] 
[Remote("UserNameExists", "Validation", "", ErrorMessage = "Username is already taken.")] 
[RegularExpression(@"(\S)+", ErrorMessage = "White space is not allowed.")] 
[Display(Name = "Username (spaces will be stripped, must be at least 6 characters long)")] 
public string UserName { get; set; } 

Validation控制器方法如下:

public class ValidationController : Controller 
{ 
    public JsonResult UserNameExists(string UserName) 
    { 
     string user = null; 
     if (!String.IsNullOrWhiteSpace(UserName) && UserName.Length >= 6) 
      user = UserName == "abcdef" ? "ok" : null; 

     return user == null ? 
      Json(true, JsonRequestBehavior.AllowGet) : 
      Json(string.Format("{0} is not available.", UserName), JsonRequestBehavior.AllowGet); 
    } 
} 

现在在注册查看,使用GlobalAccount模式,而不是RegisterModel

的用户名输入框会像:

@model Your.NameSpace.Models.GlobalAccount 

<div class="field fade-label"> 
    @Html.LabelFor(model => model.Register.UserName, new { @class = "text" }) 
    @Html.TextBoxFor(model => model.Register.UserName, new { spellcheck = "false", size = "30" }) 
</div> 

这将导致这样的事情,在HTML

<div class="field fade-label"> 
    <label class="text" for="Register_UserName"><span>Username (spaces will be stripped, must be at least 6 characters long)</span></label> 
    <input data-val="true" data-val-regex="White space is not allowed." data-val-regex-pattern="(\S)+" data-val-remote="Username is already taken." data-val-remote-additionalfields="*.UserName" data-val-remote-url="/beta/Validation/UserNameExists" data-val-required="The Username (spaces will be stripped, must be at least 6 characters long) field is required." id="Register_UserName" name="Register.UserName" size="30" spellcheck="false" type="text" value=""> 
</div> 

调试

如果用Firebug检查是怎么回事...的远程验证正在发送属性代替属性ID进入验证方法(UserNameExists一个)为:

Register.UserName代替Register_UserName

所以我不能获取该值...... 不断 :(

这真的是一个bug或者是什么,有人已经找到我无法从谷歌搜索得到它?

下面是实际的问题的一个简单的图像:

enter image description here

回答

9

如何:

public ActionResult UserNameExists(
    [Bind(Include = "UserName")]RegisterModel register 
) 
{ 
    string user = null; 
    if (!String.IsNullOrWhiteSpace(register.UserName) && register.UserName.Length >= 6) 
     user = register.UserName == "abcdef" ? "ok" : null; 

    return user == null ? 
     Json(true, JsonRequestBehavior.AllowGet) : 
     Json(string.Format("{0} is not available.", register.UserName), JsonRequestBehavior.AllowGet); 
} 

另一种可能性是定义一个特殊的视图模型:

public class UserNameExistsViewModel 
{ 
    public string UserName { get; set; } 
} 

然后:

public ActionResult UserNameExists(UserNameExistsViewModel register) 
{ 
    string user = null; 
    if (!String.IsNullOrWhiteSpace(register.UserName) && register.UserName.Length >= 6) 
     user = register.UserName == "abcdef" ? "ok" : null; 

    return user == null ? 
     Json(true, JsonRequestBehavior.AllowGet) : 
     Json(string.Format("{0} is not available.", register.UserName), JsonRequestBehavior.AllowGet); 
} 

什么是恼人的是,以下不工作:

public ActionResult UserNameExists(
    [Bind(Prefix = "Register")]string UserName 
) 

去图:-)我可能会用一个自定义的视图模型去。它看起来最干净。

+1

我在这里看着屏幕,并希望你在线达林:) ...我必须说:哇...我从来没有见过这个伎俩,工作就像一个魅力:)我们不只是喜欢知道我们最喜欢的语言的新东西:D - 我只是难过我不能添加+10 :( - 非常感谢Darin! – balexandre 2011-04-27 07:51:10

+0

我发现什么“令人讨厌”达林,适合我,在哪里绑定(包括= “bla”)没有工作。 – GoClimbColorado 2011-11-23 20:15:58

2

我知道这被标记为回答,但由于我有同样的问题,我认为我会贡献另一个变化,这对我来说是工作。

在我的情况下,类是“食物”,我试图远程验证的字段是“名称”。文本框是由一个EditorFor控件创建:

@Html.EditorFor(model => model.Name) 

远程验证设置在食品类领域:

[Remote("FoodNameExists")] 
public string Name { get; set; } 

这调用一个方法:

public ActionResult FoodNameExists(string Name) { 

由于每原始问题,而不是作为“名称”传递给FoodNameExists方法,或者甚至是由FoodFor辅助器创建的Id值的“Food_Name”,它将作为name属性传递“Food.Name”...这当然不是我可以设置为输入参数的东西。

所以,我的破解是简单地忽略输入参数,并期待在查询字符串:

var name = Request.QueryString["Food.Name"]; 

...这个返回正确的值,这是我验证对,我去比赛。

0

这是我找到的最简单的方法,只需在视图内添加DropDownListFor的HtmlAttributes中的data-val--属性即可。下面的方法与RemoteValidation工作也一样,如果你不需要远程验证,只需删除包含的元素数据-VAL-的远程*:

 @Html.DropDownListFor(m => m.yourlistID, (IEnumerable<SelectListItem>)ViewBag.YourListID, String.Empty, 
     new Dictionary<string, object>() { { "data-val", "true" }, 
     { "data-val-remote-url", "/Validation/yourremoteval" }, 
     { "data-val-remote-type", "POST" }, { "data-val-remote-additionalfield", "youradditionalfieldtovalidate" } }) 

我希望它可以帮助。最好的祝福!