Search code examples
asp.net-mvc-3action-filter

Retrieve a complex object from ActionParameters


I am working on an MVC project where controller actions deal with Assets. Different controllers take in the assetId parameter in different way: Some controllers simply get int assetId, other int id, and other using a complex object AssetDTO dto (which contains a property that holds the assetId)

I am writing an ActionFilter that is added to the action method and is provided with the actionParameter name where I can get the asset value.

Action Method:

    [AssetIdFilter("assetId")]
    public ActionResult Index(int assetId)
    {
            ...
    }

The attribute is defined as:

public class AssetIdFilterAttribute : ActionFilterAttribute
{
    public string _assetIdParameterKey { get; set; }

    public AssetIdFilterAttribute (string assetIdParameterKey)
    {
        _assetIdParameterKey = assetIdParameterKey;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        int assetId;
        if (Int32.TryParse(filterContext.ActionParameters[_assetIdParameterKey].ToString(), out assetId))
        {
                    ......
        }
    }

This works as expected, but will only work when the assetId is provided as a primitive. I am not sure what to do when the assetId is provided within a complex object into the action method.

Will I need to parse each object differently depending on the type? I am hoping I can specify some kind of dot-notation in the AssetIdFilter to tell it where the assetId is located: dto.assetId

Any way I can use dynamics? or reflection?? ect.???


Solution

  • and here dynamic comes to the rescue.you can change the actionFilterAttribute to be :

            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                dynamic assetIdHolder = filterContext.ActionParameters[_assetIdParameterKey];
                if (assetIdHolder.GetType().IsPrimitive)
                {
                    //do whatever with assetIdHolder              
                }
                else
                {
                    //do whatever with assetIdHolder.assetId
                }
            }
    

    cheers!