加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc-3 – RemoteAttribute验证器不会触发服务器端

发布时间:2020-12-16 09:59:55 所属栏目:asp.Net 来源:网络整理
导读:ASP.NET MVC 3中引入的RemoteAttribute验证器似乎不在服务器端验证,只能通过 JavaScript验证.如果在浏览器中关闭JS,您会发现在模型绑定上,验证控制器操作(在使用RemoteAttribute修饰模型属性时指定)将不会被命中.实际上,如果检查RemoteAttribute的源代码,您
ASP.NET MVC 3中引入的RemoteAttribute验证器似乎不在服务器端验证,只能通过 JavaScript验证.如果在浏览器中关闭JS,您会发现在模型绑定上,验证控制器操作(在使用RemoteAttribute修饰模型属性时指定)将不会被命中.实际上,如果检查RemoteAttribute的源代码,您会发现IsValid方法在所有情况下都返回true.

这似乎是一个遗漏 – 我想大多数人会认为RemoteAttribute会像所有其他内置验证器一样工作,并在客户端和服务器端进行验证.相反,您必须在控制器操作中手动调用远程验证逻辑.

人们是否意识到这一点并且有人试图解决这个问题?

我已经将RemoteAttribute子类化并覆盖了我可以访问RouteData,RouteName和Routes的IsValid方法以及返回操作URL的GetUrl方法.我正在考虑使用反射来调用动作并获得结果,以便我可以看到它是否有效,但是有没有内置的方法可以使用而无需借助反射?

解决方法

也许它不是最好的代码.如果您有一些建议,请告诉我.
开发@ MVC4

具有自定义属性的Model属性

[CustomRemote("ValidateIP","Validation",ErrorMessage = "Input is not a valid IP")]

Subclassed RemoteAttribute

/// <summary>
/// Custom Remote Attribute for Client an Server validation.
/// </summary>
public class CustomRemoteAttribute : RemoteAttribute
{
    /// <summary>
    /// List of all Controllers on MVC Application
    /// </summary>
    /// <returns></returns>
    private static List<Type> GetControllerList()
    {
        return Assembly.GetCallingAssembly().GetTypes().Where(type => type.IsSubclassOf(typeof(Controller))).ToList();
    }

    /// <summary>
    /// Constructor of base class.
    /// </summary>
    protected CustomRemoteAttribute()
    {
    }

    /// <summary>
    /// Constructor of base class.
    /// </summary>
    public CustomRemoteAttribute(string routeName)
        : base(routeName)
    {
    }

    /// <summary>
    /// Constructor of base class.
    /// </summary>
    public CustomRemoteAttribute(string action,string controller)
        : base(action,controller)
    {
    }

    /// <summary>
    /// Constructor of base class.
    /// </summary>
    public CustomRemoteAttribute(string action,string controller,string areaName)
        : base(action,controller,areaName)
    {
    }

    /// <summary>
    /// Overridden IsValid function
    /// </summary>
    /// <param name="value"></param>
    /// <param name="validationContext"></param>
    /// <returns></returns>
    protected override ValidationResult IsValid(object value,ValidationContext validationContext)
    {
        // Find the controller passed in constructor
        var controller = GetControllerList().FirstOrDefault(x => x.Name == string.Format("{0}Controller",this.RouteData["controller"]));
        if (controller == null)
        {
            // Default behavior of IsValid when no controller is found.
            return ValidationResult.Success;
        }

        // Find the Method passed in constructor
        var mi = controller.GetMethod(this.RouteData["action"].ToString());
        if (mi == null)
        {
            // Default behavior of IsValid when action not found
            return ValidationResult.Success;
        }

        // Create instance of the controller to be able to call non static validation method
        var instance = Activator.CreateInstance(controller);

        // invoke the method on the controller with value
        var result = (JsonResult)mi.Invoke(instance,new object[] { value });

        // Return success or the error message string from CustomRemoteAttribute
        return (bool) result.Data ? ValidationResult.Success : new ValidationResult(base.ErrorMessageString);
    }
}

验证控制器代码

/// <summary>
/// Controller for Client and Server validation
/// <remarks>disable OutputCache</remarks>
/// </summary>
[OutputCache(Location = OutputCacheLocation.None,NoStore = true)]
public class ValidationController : Controller
{
    /// <summary>
    /// !!!!!!!!!!!!!!!!!! Needed for instance creation in custom attribute !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    /// </summary>
    public ValidationController()
    {
    }

    /// <summary>
    /// IP regex pattern of my choice
    /// </summary>
    const string IpPattern = @"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";

    /// <summary>
    /// MAC regex pattern of my choice
    /// </summary>
    const string MacPattern = "^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$";

    /// <summary>
    /// Validate IP
    /// </summary>
    /// <param name="ip">IP param is only submited on Serverside validation!!!</param>
    /// <returns>Validation Result</returns>
    public JsonResult ValidateIP(string ip)
    {
        // Check if ip and httpcontext is null to dodge NullReferenceException on Server side validation
        if (string.IsNullOrEmpty(ip) && HttpContext == null)
        {
            return Json(false,JsonRequestBehavior.AllowGet);
        }

        /* Use IP on Serverside validation 
         * Use Querystring Param 0 to get IP from Client side vaildation without the need for the correct Id of input control */
        string checkip = string.IsNullOrEmpty(ip) ? HttpContext.Request.QueryString[0] : ip;
        if (string.IsNullOrEmpty(checkip))
        {
            return new JsonResult { Data = true,JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        return new JsonResult
            {
                Data = Regex.IsMatch(checkip,IpPattern),JsonRequestBehavior = JsonRequestBehavior.AllowGet
            };
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读