转换自定义操作过滤器对Web API的使用? [英] Convert custom action filter for Web API use?

查看:165
本文介绍了转换自定义操作过滤器对Web API的使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了一个非常好的行动的过滤器,转换成以逗号分隔的参数泛型类型列表:<一href=\"http://stevescodingblog.co.uk/fun-with-action-filters/\">http://stevescodingblog.co.uk/fun-with-action-filters/

我想用它,但它不会为一个ApiController工作,它完全忽略它。谁能帮这个转换的Web API使用?

  [AttributeUsage(AttributeTargets.Method)
公共类SplitStringAttribute:ActionFilterAttribute
{
    公共字符串参数{搞定;组; }    公共字符串分隔符{搞定;组; }    公共SplitStringAttribute()
    {
        定界符=,;
    }    公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
    {
        如果(filterContext.ActionParameters.ContainsKey(this.Parameter))
        {
            字符串值= NULL;
            VAR请求= filterContext.RequestContext.HttpContext.Request;            如果(filterContext.RouteData.Values​​.ContainsKey(this.Parameter)
                &功放;&安培; filterContext.RouteData.Values​​ [this.Parameter]是字符串)
            {
                值=(字符串)filterContext.RouteData.Values​​ [this.Parameter]
            }
            否则,如果(要求[this.Parameter]是字符串)
            {
                值=请求[this.Parameter]作为字符串;
            }            VAR listArgType = GetParameterEnumerableType(filterContext);            如果(listArgType = NULL&放大器;!&安培;!string.IsNullOrWhiteSpace(值))
            {
                字符串[] =值value.Split(Delimiter.ToCharArray(),StringSplitOptions.RemoveEmptyEntries);                VAR listType = typeof运算(名单&LT;&GT;)MakeGenericType(listArgType)。
                动态列表= Activator.CreateInstance(listType);                的foreach(中值VAR项)
                {
                    尝试
                    {
                        动态convertedValue = TypeDescriptor.GetConverter(listArgType).ConvertFromInvariantString(项目);
                        list.Add(convertedValue);
                    }
                    赶上(异常前)
                    {
                        抛出新ApplicationException的(的String.Format(无法​​转换分割字符串值{0}',listArgType.FullName),前);
                    }
                }                filterContext.ActionParameters [this.Parameter] =清单;
            }
        }        base.OnActionExecuting(filterContext);
    }    私有类型GetParameterEnumerableType(ActionExecutingContext filterContext)
    {
        VAR参数= filterContext.ActionParameters [this.Parameter]
        变种paramType = param.GetType();
        VAR interfaceType = paramType.GetInterface(typeof运算(IEnumerable的&LT;&GT;)全名);
        键入listArgType = NULL;        如果(interfaceType!= NULL)
        {
            变种genericParams = interfaceType.GetGenericArguments();
            如果(genericParams.Length == 1)
            {
                listArgType = genericParams [0];
            }
        }        返回listArgType;
    }
}


解决方案

你在使用命名空间 ActionFilterAttribute ?对于Web API,您需要使用 System.Web.Http.Filters 命名空间,而不是 System.Web.Mvc

修改

下面是一个粗略的转换,而不是全面测试。

SplitStringAttribute

 使用系统;
使用System.Collections.Generic;
使用System.ComponentModel;
使用System.Net.Http;
使用System.Web.Http.Controllers;
使用System.Web.Http.Filters;命名空间StackOverflowSplitStringAttribute.Infrastructure.Attributes
{
    [AttributeUsage(AttributeTargets.Method)
    公共类SplitStringAttribute:ActionFilterAttribute
    {
        公共字符串参数{搞定;组; }        公共字符串分隔符{搞定;组; }        公共SplitStringAttribute()
        {
            定界符=,;
        }        公共覆盖无效OnActionExecuting(HttpActionContext filterContext)
        {
            如果(filterContext.ActionArguments.ContainsKey(参数))
            {
                变种适量= filterContext.Request.RequestUri.ParseQueryString();
                如果(qs.HasKeys())
                {
                    VAR值= QS [参数]                    VAR listArgType = GetParameterEnumerableType(filterContext);                    如果(listArgType = NULL&放大器;!&安培;!string.IsNullOrWhiteSpace(值))
                    {
                        字符串[] =值value.Split(Delimiter.ToCharArray(),StringSplitOptions.RemoveEmptyEntries);                        VAR listType = typeof运算(名单&LT;&GT;)MakeGenericType(listArgType)。
                        动态列表= Activator.CreateInstance(listType);                        的foreach(中值VAR项)
                        {
                            尝试
                            {
                                动态convertedValue = TypeDescriptor.GetConverter(listArgType).ConvertFromInvariantString(项目);
                                list.Add(convertedValue);
                            }
                            赶上(异常前)
                            {
                                抛出新ApplicationException的(的String.Format(无法​​转换分割字符串值{0}',listArgType.FullName),前);
                            }
                        }                        filterContext.ActionArguments [参数] =清单;
                    }
                }
            }            base.OnActionExecuting(filterContext);
        }        私有类型GetParameterEnumerableType(HttpActionContext filterContext)
        {
            VAR参数= filterContext.ActionArguments [参数]
            变种paramType = param.GetType();
            VAR interfaceType = paramType.GetInterface(typeof运算(IEnumerable的&LT;&GT;)全名);
            键入listArgType = NULL;            如果(interfaceType!= NULL)
            {
                变种genericParams = interfaceType.GetGenericArguments();
                如果(genericParams.Length == 1)
                {
                    listArgType = genericParams [0];
                }
            }            返回listArgType;
        }    }
}

CsvController

 使用System.Web.Http;
使用System.Collections.Generic;
使用StackOverflowSplitStringAttribute.Infrastructure.Attributes;命名空间StackOverflowSplitStringAttribute.Controllers
{
    公共类CsvController:ApiController
    {        // GET / API /值        [SplitString(参数=数据)]
        公共IEnumerable的&LT;串GT;获取(IEnumerable的&LT;串GT;数据)
        {
            返回的数据;
        }
    }
}

示例要求

 的http://本地主机:52595 / API / CSV数据=这是一个,测试,乔

I found a really nice action filter that converts a comma-separated parameter to a generic type list: http://stevescodingblog.co.uk/fun-with-action-filters/

I would like to use it but it will not work for an ApiController, it completely ignore it. Can someone help convert this for Web API use?

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

    public string Delimiter { get; set; }

    public SplitStringAttribute()
    {
        Delimiter = ",";
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.ActionParameters.ContainsKey(this.Parameter))
        {
            string value = null;
            var request = filterContext.RequestContext.HttpContext.Request;

            if (filterContext.RouteData.Values.ContainsKey(this.Parameter)
                && filterContext.RouteData.Values[this.Parameter] is string)
            {
                value = (string)filterContext.RouteData.Values[this.Parameter];
            }
            else if (request[this.Parameter] is string)
            {
                value = request[this.Parameter] as string;
            }

            var listArgType = GetParameterEnumerableType(filterContext);

            if (listArgType != null && !string.IsNullOrWhiteSpace(value))
            {
                string[] values = value.Split(Delimiter.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

                var listType = typeof(List<>).MakeGenericType(listArgType);
                dynamic list = Activator.CreateInstance(listType);

                foreach (var item in values)
                {
                    try
                    {
                        dynamic convertedValue = TypeDescriptor.GetConverter(listArgType).ConvertFromInvariantString(item);
                        list.Add(convertedValue);
                    }
                    catch (Exception ex)
                    {
                        throw new ApplicationException(string.Format("Could not convert split string value to '{0}'", listArgType.FullName), ex);
                    }
                }

                filterContext.ActionParameters[this.Parameter] = list;
            }
        }

        base.OnActionExecuting(filterContext);
    }

    private Type GetParameterEnumerableType(ActionExecutingContext filterContext)
    {
        var param = filterContext.ActionParameters[this.Parameter];
        var paramType = param.GetType();
        var interfaceType = paramType.GetInterface(typeof(IEnumerable<>).FullName);
        Type listArgType = null;

        if (interfaceType != null)
        {
            var genericParams = interfaceType.GetGenericArguments();
            if (genericParams.Length == 1)
            {
                listArgType = genericParams[0];
            }
        }

        return listArgType;
    }
}

解决方案

What namespace are you using for ActionFilterAttribute? For Web API you need to be using System.Web.Http.Filters namespace and not System.Web.Mvc.

EDIT

Here's a rough conversion, not fully tested.

SplitStringAttribute

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;

namespace StackOverflowSplitStringAttribute.Infrastructure.Attributes
{
    [AttributeUsage(AttributeTargets.Method)]
    public class SplitStringAttribute : ActionFilterAttribute
    {
        public string Parameter { get; set; }

        public string Delimiter { get; set; }

        public SplitStringAttribute()
        {
            Delimiter = ",";
        }

        public override void OnActionExecuting(HttpActionContext filterContext)
        {
            if (filterContext.ActionArguments.ContainsKey(Parameter))
            {
                var qs = filterContext.Request.RequestUri.ParseQueryString();
                if (qs.HasKeys())
                {
                    var value = qs[Parameter];

                    var listArgType = GetParameterEnumerableType(filterContext);

                    if (listArgType != null && !string.IsNullOrWhiteSpace(value))
                    {
                        string[] values = value.Split(Delimiter.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

                        var listType = typeof(List<>).MakeGenericType(listArgType);
                        dynamic list = Activator.CreateInstance(listType);

                        foreach (var item in values)
                        {
                            try
                            {
                                dynamic convertedValue = TypeDescriptor.GetConverter(listArgType).ConvertFromInvariantString(item);
                                list.Add(convertedValue);
                            }
                            catch (Exception ex)
                            {
                                throw new ApplicationException(string.Format("Could not convert split string value to '{0}'", listArgType.FullName), ex);
                            }
                        }

                        filterContext.ActionArguments[Parameter] = list;
                    }
                }
            }

            base.OnActionExecuting(filterContext);
        }

        private Type GetParameterEnumerableType(HttpActionContext filterContext)
        {
            var param = filterContext.ActionArguments[Parameter];
            var paramType = param.GetType();
            var interfaceType = paramType.GetInterface(typeof(IEnumerable<>).FullName);
            Type listArgType = null;

            if (interfaceType != null)
            {
                var genericParams = interfaceType.GetGenericArguments();
                if (genericParams.Length == 1)
                {
                    listArgType = genericParams[0];
                }
            }

            return listArgType;
        }

    }
}

CsvController

using System.Web.Http;
using System.Collections.Generic;
using StackOverflowSplitStringAttribute.Infrastructure.Attributes;

namespace StackOverflowSplitStringAttribute.Controllers
{
    public class CsvController : ApiController
    {

        // GET /api/values

        [SplitString(Parameter = "data")]
        public IEnumerable<string> Get(IEnumerable<string> data)
        {
            return data;
        }
    }
}

Example request

http://localhost:52595/api/csv?data=this,is,a,test,joe

这篇关于转换自定义操作过滤器对Web API的使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆