7

我正在开发一个 MVC 项目,其中控制器操作处理资产。不同的控制器以不同的方式获取assetId 参数:一些控制器简单地获取int assetId、其他int id和其他使用复杂对象AssetDTO dto(其中包含保存assetId 的属性)

我正在编写一个 ActionFilter,它被添加到 action 方法中,并提供了 actionParameter 名称,我可以在其中获取资产值。

行动方法:

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

该属性定义为:

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))
        {
                    ......
        }
    }

这可以按预期工作,但仅当assetId 作为原语提供时才有效。我不确定在将复杂对象中的assetId 提供给操作方法时该怎么做。

我需要根据类型对每个对象进行不同的解析吗?我希望我可以在 AssetIdFilter 中指定某种点符号来告诉它assetId 的位置:dto.assetId

有什么办法可以使用动态?还是反思??等等???

4

2 回答 2

8

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!

于 2012-11-24T06:10:19.533 回答
0

嗯,是的,你回答了你的问题。一种方法是使用点表示法:

//simple case:
[AssetId("id")]
public ActionResult Index(string id) {
    //code here
}

//complex case:
[AssetId("idObj", AssetIdProperty = "SubObj.id")]
public ActionResult index(IdObject idObj) {
    //code here
}

AssetIdAttribute如下:

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

    public string AssetIdProperty { get; set; }

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

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        int assetId;
        var param = filterContext.ActionParameters[_assetIdParameterKey];
        int.TryParse(GetPropertyValue(param, this.AssetIdProperty).ToString(), out assetId);
        //you code continues here.
    }

    private static string GetPropertyValue(object souce, string property)
    {
        var propNames = string.IsNullOrWhiteSpace(property) || !property.Contains('.') ? new string[] { } : property.Split('.');
        var result = souce;
        foreach (var prop in propNames)
        {
            result = result.GetType().GetProperty(prop).GetValue(result);
        }
        return result.ToString();
    }
}

ToString该代码在调用时和调用时没有空检查GetProperty。此外,它不会检查TryParse. 请在使用时应用这些更正。

也许这段代码可以使用 编写dynamic,但最后dynamic使用反射编译成对象(就像我在这里所做的那样),因此对我来说没有太大区别。

此外,也许有一个像“idObj.SubObj.id”这样的参数会更清楚,但这又取决于偏好,代码会变得有点复杂。

于 2012-11-30T18:10:48.573 回答