转换自定义操作过滤器对Web API的使用? [英] Convert custom action filter for Web API use?
问题描述
我发现了一个非常好的行动的过滤器,转换成以逗号分隔的参数泛型类型列表:<一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屋!