【问题标题】:Setting up routing when RemoteAttribute specifies AdditionalFields当 RemoteAttribute 指定 AdditionalFields 时设置路由
【发布时间】:2015-06-15 15:47:47
【问题描述】:

如果我通过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 个按名称匹配的操作):

当前对控制器类型“ValidationController”的操作“IsUserNameAvailable”的请求在以下操作方法之间不明确:

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

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

【问题讨论】:

  • 发送的实际请求或查询字符串是什么样的?
  • 你真的需要在帖子中展示SQL注入示例吗?我认为这与您的问题无关。
  • @AlexeiLevenkov - 我的代码不对 SQL 注入开放。 GetBySqlStatement 参数化了一切。
  • 这里链接的问题根本不是重复的。链接的问题与远程属性参数无关,都是关于路由的。
  • 请确保编辑您的问题以澄清这一点 - 到目前为止,看起来像 MVC 路由匹配 2 个请求操作的基本问题。可能您可以减少样本以同时删除 SQL 内容。

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


【解决方案1】:

实际上,从 MVC 的角度来看,IsUserNameAvailable(string userName)IsUserNameAvailable(string userName, string UserId) 确实是同一件事(因此使用了“模糊”一词)。

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

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

【讨论】:

  • "really is the same thing" 有点牵强,但足够接近 :) 在搜索与IsUserNameAvailable 匹配的路由时确实会找到两者,并且在 ASP.Net MVC 中无法消除歧义通过方法中的参数列表执行操作。
  • 我明白你的意思。我已经更新了我的答案以澄清更多。
【解决方案2】:

当它收到/Validation/IsUserNameAvailable?userName=BOB&UserID= 之类的查询时,MVC 的模型绑定器会感到困惑,因为它不知道如何处理空/空字符串参数。只需将参数更改为 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);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-08
    • 2020-09-27
    • 1970-01-01
    • 2022-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-06
    相关资源
    最近更新 更多