在为泛型方法指定Type时尝试使用Type参数时出错。
错误:'JsonFilter.JsonDataType'是'属性',但用作'type'
public class JsonFilter : ActionFilterAttribute
{
public Type JsonDataType { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
...
JavaScriptSerializer jss = new JavaScriptSerializer();
var result = jss.Deserialize<JsonDataType>(inputContent);//Error here
...
新代码
...
JavaScriptSerializer jss = new JavaScriptSerializer();
MethodInfo method = jss.GetType()
.GetMethod("Deserialize")
.MakeGenericMethod(new Type[] { JsonDataType });
var result = method.Invoke(jss, new object[] { inputContent });
filterContext.ActionParameters[Param] = result;
...
反射可以节省一天。感谢@Jason解释当type被指定为泛型方法的一部分(&lt; Typename &gt;)时,它会被编译成字节。而作为属性,它可以是任何类型,只能在运行时确定。
更新
对于此特定问题,以下代码更简洁。
var o = new DataContractJsonSerializer(JsonDataType).ReadObject(
filterContext.HttpContext.Request.InputStream);
filterContext.ActionParameters[Param] = o;
答案 0 :(得分:14)
错误
错误:'
JsonFilter.JsonDataType
'是'属性',但用作“类型”
告诉你确切的问题。
var result = jss.Deserialize<JsonDataType>(inputContent);
在这里,您尝试将JsonDataType
作为类型参数传递给通用方法JavaScriptSerializer.Deserialize<T>
但是这里
public Type JsonDataType { get; set; }
您将JsonDataType
声明为Type
类型的属性,但不是类型。要使用泛型方法,您需要传递一个类型参数(或者,在某些情况下,让编译器推断一个)。例如
var result = jss.Deserialize<string>(inputContent);
是正确的用法,因为string
是一种类型。
现在,如果您绝对想要使用由JsonDataType
表示的类型,则可以使用反射。
MethodInfo generic = typeof(JavaScriptSerializer).GetMethod("Deserialize")
.GetGenericMethodDefinition();
MethodInfo closed = generic.MakeGenericMethod(new [] { JsonDataType });
closed.Invoke(jss, new object[] { inputContent });
答案 1 :(得分:5)
由于您无法在类中添加泛型类型参数,因此您需要使用反射:
public class JsonFilter : ActionFilterAttribute
{
public Type JsonDataType { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// ...
JavaScriptSerializer jss = new JavaScriptSerializer();
MethodInfo method = jss.GetType()
.GetMethod("Deserialize");
.MakeGenericMethod(new Type[] { JsonDataType });
var result = method.Invoke(jss, new object[] { inputContent });
//...
}
}
原创,错误回答......
<击>
您可以使用泛型类型参数而不是JsonDataType
属性吗?
public class JsonFilter<TJsonData> : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// ...
JavaScriptSerializer jss = new JavaScriptSerializer();
var result = jss.Deserialize<TJsonData>(inputContent);
//...
}
}
击> <击> 撞击>
答案 2 :(得分:2)
沿着这些方向尝试这个。我会在一秒钟内为您的代码更新它。
typeof(IDependencyResolver).GetMethod("Resolve", new Type[] { })
.MakeGenericMethod(type)
.Invoke(this, null);
这是给你的草稿。
typeof(JavaScriptSerializer).GetMethod("Deserialize", new Type[] {} /* param types */)
.MakeGenericMethod(JsonDataType).Invoke(jss, /*params*/);
基本上它使用反射来调用泛型方法。
答案 3 :(得分:2)
你不能以这种方式传递泛型类型的参数 - 尝试这样的事情:
public class JsonFilter<T> : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
var result = jss.Deserialize<T>(inputContent);//Error here
}
}
不要在属性中设置类型,而是将JsonFilter
类设为通用类,以便将泛型类型参数传递给JavaScriptSerializer
。