RemoteAttribute验证不火的服务器端 [英] RemoteAttribute validator does not fire server-side

查看:497
本文介绍了RemoteAttribute验证不火的服务器端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前看来,在ASP.NET MVC 3推出RemoteAttribute验证不验证的服务器端,只通过JavaScript。如果您在您的浏览器禁用JS,你会发现,在模型绑定,验证控制器动作(你装饰与RemoteAttribute一个模型属性时指定)将不会被击中。事实上,如果你检查源$ C ​​$ C为RemoteAttribute,你会发现IsValid的方法,只是在所有情况下返回true。

It appears that the RemoteAttribute validator introduced in ASP.NET MVC 3 does not validate on the server-side, only via JavaScript. If you turn off JS in your browser, you will find that on model binding, the validation controller action (that you specified when decorating a model property with the RemoteAttribute) will not be hit. In fact, if you inspect the source code for the RemoteAttribute, you will find the IsValid methods just returns true in all cases.

这似乎是相当不作为 - 我想大多数人都会假定RemoteAttribute将工作像所有其他内置的验证和验证两个客户端和服务器端。相反,您必须手动调用远程验证逻辑控制器的动作。

This seems to be quite an omission - I think most people would assume that the RemoteAttribute would work like all the other built-in validators and validate on both client-side and server-side. Instead, you must manually call your remote validation logic in your controller action.

人们是否意识到这一点,有没有人试图解决它?

Are people aware of this and has anyone tried to address it?

我已经子类RemoteAttribute和重写IsValid的方法,在那里我有机会获得的RouteData,RouteName和路线以及返回的动作的URL getURL方法。我想使用反射来调用的行动,得到的结果,所以我可以看到,如果它是有效还是无效,但是否有任何内置的方法,我可以不诉诸反射使用?

I have subclassed RemoteAttribute and overridden the IsValid method where I have access to RouteData, RouteName and Routes as well as a GetUrl method that returns the action URL. I was thinking about using reflection to call the action and get the result so I can see if it is valid or not, but are there any built-in methods that I can use without resorting to reflection?

推荐答案

也许它不是最好的code。如果你有一些建议,请让我知道。
开发@ MVC4

Maybe its not the best code. If you have some recommendations please let me know. Developed @MVC4

Model属性与自定义属性

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

子类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);
    }
}

验证控制器code

/// <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
            };
    }
}

这篇关于RemoteAttribute验证不火的服务器端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆