RemoteAttribute指定AdditionalFields时设置路由

时间:2015-06-15 15:47:47

标签: c# asp.net asp.net-mvc asp.net-mvc-4

如果我通过RemoteAttribute指定AdditionalFields进行验证以处理可能的可选附加字段,如何配置操作?目前,我尝试对可选字段的可能组合进行操作,但它不能如下所示。

我有一个绑定到模型的表单,其中一个字段是用户名的远程验证字段。当我运行程序时,我收到一个错误。这是我的验证码:

[OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
public class ValidationController : Controller
{
    public JsonResult IsUserNameAvailable(string userName)
    {
        // compute condition, only "fail" shown.
        return Json(string.Format("{0} is already taken.", userName), 
            JsonRequestBehavior.AllowGet);
    }

    public JsonResult IsUserNameAvailable(string userName, string UserId)
    {
        // compute condition using both name and ID, only "fail" shown.
        return Json(string.Format("{0} is already taken.", userName),
             JsonRequestBehavior.AllowGet);
    }
}

这是我的模特:

public class EditUserAdministrationViewModel
{
    public int UserId { get; set; }

    [Required(ErrorMessage = "You must enter a first name.")]
    [Display(Name = "First Name")]
    public string FirstName { get; set; }

    [Required(ErrorMessage = "You must enter a user name.")]
    [Display(Name = "User Name")]
    [Remote("IsUserNameAvailable", "Validation", AdditionalFields = "UserId")]
    public string UserName { get; set; }

    // more fileds 
}

确实我收到了运行时错误(因为Routing: The current request for action [...] is ambiguous between the following action methods中有2个按名称匹配的操作):

  

当前的行动请求' IsUserNameAvailable'在控制器类型' ValidationController'以下操作方法之间存在歧义:

     

类型为BdsManager.Controllers.ValidationController的System.Web.Mvc.JsonResult IsUserNameAvailable(System.String)

     

类型为BdsManager.Controllers.ValidationController的System.Web.Mvc.JsonResult IsUserNameAvailable(System.String,System.String)

2 个答案:

答案 0 :(得分:1)

实际上,IsUserNameAvailable(string userName)IsUserNameAvailable(string userName, string UserId)从MVC的角度来看确实是同样的事情(因此术语“含糊不清”)。

调用它时,.NET会尝试使用查询字符串参数或POST正文中的项来填充所有参数。由于字符串对象不可为空,因此它将向UserId传递一个空字符串,而不是null。这意味着,UserId始终存在,作为空字符串。然后.NET变得混乱,因为它有一个可以调用的函数,只需提供字符串userName,但它还可以通过提供两个参数来调用另一个函数。

最好是创建一个函数并检查UserId是否为空。

答案 1 :(得分:0)

当它收到诸如/Validation/IsUserNameAvailable?userName=BOB&UserID=的查询时,MVC的模型绑定器会混淆,因为它不知道如何处理null / empty字符串参数。只需将参数更改为int并根据辅助方法的需要进行强制转换:

public JsonResult IsUserNameAvailable(string userName, int UserId)
{
    var users = new BusinessLayer.BdsAdmin.Users();
    users.GetBySqlStatement("SELECT * FROM [User] WHERE [UserName]='{0}' AND [UserId]<>{1}", userName, (int)UserId);    // add some exception safe conversion of types here

    if (users.Count == 0)
    {
        return Json(true, JsonRequestBehavior.AllowGet);
    }

    string msg = string.Format("{0} is already taken and is not available.", userName);
    return Json(msg, JsonRequestBehavior.AllowGet);
}

更好的是,将它们组合成一个带有可空/可选参数的方法:

public JsonResult IsUserNameAvailable(string userName, int? UserId)
{
    var users = new BusinessLayer.BdsAdmin.Users();
    if (UserId.HasValue)
    {
        users.GetBySqlStatement("SELECT * FROM [User] WHERE [UserName]='{0}' AND [UserId]<>{1}", userName, UserId.Value);
    } else {
        users.GetBySqlStatement("SELECT * FROM [User] WHERE [UserName]='{0}'", userName);
    }

    if (users.Count == 0)
    {
        return Json(true, JsonRequestBehavior.AllowGet);
    }

    string msg = string.Format("{0} is already taken and is not available.", userName);
    return Json(msg, JsonRequestBehavior.AllowGet);
}