Asp.net-mvc – ASP.NET MVC – An attribute argument must be a constant expression

asp.net-mvccustom-attributes

I'm trying to create a custom attribute to validate a session state in every action method of my MVC 5 app.

This is the code of the custom attribute.

[AttributeUsage(AttributeTargets.Method)]
public class CheckSession : ActionFilterAttribute
{
    public string SessionKey { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.ActionParameters.ContainsKey(SessionKey))
        {
            string value = filterContext.ActionParameters[SessionKey] as string;

            if ((string)filterContext.HttpContext.Session[value] == null)
            {
                var control = filterContext.Controller as Controller;

                if (control != null)
                {
                    filterContext.Result = new RedirectToRouteResult(
                        new System.Web.Routing.RouteValueDictionary
                        {
                            {"controller", "Home"},
                            {"action", "Error"}, 
                            {"area", ""}
                        }
                    );
                }
            }
            else
            {
                base.OnActionExecuting(filterContext);
            }
        }
    }
}

The constants for the session keys that I'm using:

public static class SessionKeysConstants
{
    public static readonly string SMSNotificationsSearchClient = "SMSNotificationsSearchClient";
}

And I'm using the custom attribute like this:

[CheckSession(SessionKey = SessionKeysConstants.SMSNotificationsSearchClient)]
public ActionResult Index()
{
    // You need a session to enter here!
    return View("Index");
}

And getting the following error:

An attribute argument must be a constant expression, typeof expression
or array creation expression of an attribute parameter type

I don't understand why, I'm using a constant and only works in assign a value string directly to the SessionKey parameter.

Best Answer

Attribute parameters are restricted to constant values of the following types:

  • Simple types (bool, byte, char, short, int, long, float, and double)
  • string
  • System.Type
  • enums
  • object (The argument to an attribute parameter of type object must be a constant value of one of the above types.)
  • One-dimensional arrays of any of the above types

Reference: https://msdn.microsoft.com/en-us/library/aa288454(v=vs.71).aspx

You can resolve your problem if you define SessionKeysConstants as an enum. And for that enum, one named constant is SMSNotificationsSearchClient.

As @StephenMuecke said above you can also make your string const too.

I would prefer an enum, this is somehow a standard if you're looking to data annotations(for example): https://msdn.microsoft.com/en-us/library/dd901590(VS.95).aspx

Basically your SessionKeysConstants is an enumeration of named constants, which by definition is an enum, but this is just my personal opinion.