C# – How to pass an attribute parameter type with List in C#

asp.net-mvcc

How can I pass a List to a construtor?

It shows a message:

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

public class CustomAuthorize : AuthorizeAttribute {
    private List<string> multipleProgramID;

    //constructor
    public CustomAuthorize(List<string> _multipleProgramID) {
        multipleProgramID = _multipleProgramID;
    }
}

[CustomAuthorize(new List<string>(new string[] { ProgramList.SURVEY_INPUT, ProgramList.SURVEY_OUTPUT } ))]
[HttpPost]
public ActionResult DeleteWaterQualityItems(string sourceID, string wqID) {
    // ..other code...
}

public class ProgramList {
    public const string SURVEY_INPUT = "A001";
    public const string SURVEY_INPUT = "A002";
}

Best Answer

The problem isn't passing a List<string> to a constructor in general - the problem is that you're trying to use it for an attribute. You basically can't do that, because it's not a compile-time constant.

It looks like ProgramList is effectively an enum - so you might want to make it an enum instead:

 [Flags]
 public enum ProgramLists
 {
     SurveyInput,
     SurveyOutput,
     ...
 }

Then make your CustomAuthorizeAttribute (which should be named like that, with a suffix of Attribute) accept a ProgramLists in the constructor. You'd specify it as:

[CustomAuthorize(ProgramLists.SurveyInput | ProgramLists.SurveyOutput)]

You can then have a separate way of mapping each ProgramLists element to a string such as "A001". This could be done by applying an attribute to each element, or maybe having a Dictionary<ProgramLists, string> somewhere.

If you really want to keep using strings like this, you could make CustomAuthorizeAttribute accept a single comma-separated list, or make it an array instead of a list and use a parameter array:

[AttributeUsage(AttributeTargets.Method)]
public class FooAttribute : Attribute
{
    public FooAttribute(params string[] values)
    {
        ...
    }
}

[Foo("a", "b")]
static void SomeMethod()
{
}