Kar Inter
Kar Inter

Reputation: 303

HandleErrorAttribute doesnt work

I have this class :

 public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }
}

and call that from Global.asax in Application_start method like this :

    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

I have this URL :

localhost:7708/blog/Index/12

Index Method is :

 public virtual ActionResult Index(int code, string title)
    {
        var result = _pageService.Get(code.ToUrlDecription());
        return View(result);
    }

I want when url doesn't have code (12) return to 404.html . for this I set these in web.config :

 <httpErrors errorMode="Custom">
  <remove statusCode="404" />
  <error statusCode="404" path="404.html" responseMode="File" />
  <remove statusCode="500" />
  <error statusCode="500" path="500.html" responseMode="File" />
</httpErrors>

but when I have this url :

localhost:7708/blog/Index

its return :

The parameters dictionary contains a null entry for parameter 'code' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Index(Int32, System.String)' in 'IAS.Store.Web.Controllers.BlogController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.

Upvotes: 1

Views: 127

Answers (1)

Bob Dust
Bob Dust

Reputation: 2460

You probably need to customize error attribute:

    [AttributeUsage(AttributeTargets.Method)]
    public class MissingParamAttribute : HandleErrorAttribute
    {
        private string _paramName;

        public MissingParamAttribute(string paramName)
        {
            _paramName = paramName;
        }

        public override void OnException(ExceptionContext filterContext)
        {
            if(filterContext.Exception is ArgumentException)
            {
                const string pattern = @"The parameters dictionary contains a null entry for parameter '([^']+)'.+";
                var match = Regex.Match(filterContext.Exception.Message, pattern, RegexOptions.Multiline);
                if(match.Success && match.Groups[1].Value == _paramName)
                {
                    filterContext.ExceptionHandled = true;
                    filterContext.HttpContext.Response.Clear();
                    filterContext.HttpContext.Response.StatusCode = 404;
                    return;
                }
            }
            base.OnException(filterContext);
        }
    }

and apply that customized attribute on your Index action:

[MissingParam("code")]
public ActionResult Index(int code, string title)
{
    var result = _pageService.Get(code.ToUrlDescription());
    return View(result);
}

Upvotes: 2

Related Questions