Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 3 从ActionParameters检索复杂对象_Asp.net Mvc 3_Action Filter - Fatal编程技术网

Asp.net mvc 3 从ActionParameters检索复杂对象

Asp.net mvc 3 从ActionParameters检索复杂对象,asp.net-mvc-3,action-filter,Asp.net Mvc 3,Action Filter,我正在从事一个MVC项目,其中控制器操作处理资产。不同的控制器以不同的方式获取assetId参数:一些控制器仅获取int-assetId,其他int-id,其他控制器使用复杂对象AssetTo-dto(其中包含保存assetId的属性) 我正在编写一个ActionFilter,它添加到action方法中,并提供actionParameter名称,从中可以获取资产值 行动方法: [AssetIdFilter("assetId")] public ActionResult Index

我正在从事一个MVC项目,其中控制器操作处理资产。不同的控制器以不同的方式获取assetId参数:一些控制器仅获取
int-assetId
,其他
int-id
,其他控制器使用复杂对象
AssetTo-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在复杂对象中提供到action方法中时,我不确定该怎么办

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


我能用动力学吗?还是反思??ect.?

这里有动态来拯救。您可以将actionFilterAttribute更改为:

        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
            }
        }

干杯

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

//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”的参数,但这同样取决于首选项,代码将变得更复杂一些