我有一个由WebAPI自动序列化的对象,但我想将其包装起来为我的数据提供上下文。一个例子是:
public class SecureModel<T>
{
public string Info { get; set; }
public T Data { get; set; }
}
这序列化/反序列化我的JSON请求没问题,一切都很好。但是,我想在允许请求完成执行之前验证一些Info,所以我添加了一个ActionFilter,我正在检索POST的参数。
public class MyAuth : System.Web.Http.Filters.ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
var arg = actionContext.ActionArguments.FirstOrDefault().Value;
// arg: get the Info?
// if the info isn't correct, return a specific Response.
}
}
当我检查这个论点时,它正是我需要的,但是我无法弄清楚如何在没有指定实际泛型类型的情况下弱化它到SecureModel。我觉得我应该能够将其置于SecureModel&lt; object&gt;并正确访问root,但它不允许这样做。到目前为止,我只能使用我需要的数据:
var notStrongEnough = arg.GetType().GetProperty("Info");
但是,我宁愿不使用反射,我也很难在没有答案的情况下前进。在这种情况下,我的替代方法是将Data更改为字符串并手动序列化/反序列化JSON对象,但这会破坏使用Web API而不是MVC3的一些目的。
注意:更改设计以使SecureModel成为基类会增加我在数据上执行的一些哈希的挑战,所以我不想走这条路。< / p>
谢谢!
修改:错位标题。
答案 0 :(得分:3)
C#中此类问题的典型解决方案是创建泛型类型实现的非泛型接口。例如,与您的班级:
public class SecureModel<T>
{
public string Info { get; set; }
public T Data { get; set; }
}
您可以定义一个界面ISecureModel
:
public interface ISecureModel
{
string Info { get; }
object Data { get; }
}
现在您可以在数据类中实现它:
public class SecureModel<T> : ISecureModel
{
public string Info { get; set; }
public T Data { get; set; }
object ISecureModel.Data {
get { return Data; }
}
}
我们在这里使用显式接口实现,因为属性object
的非泛型(T
)和泛型(Data
)版本会发生冲突。
现在,要获取信息,您只需转发到ISecureModel
。
答案 1 :(得分:1)
我个人会选择创建单独的无类型接口并实现它:
interface IObjectTypeSercureModel
{
object GetData();
string GetInfo();
}
但是,您可以将getter和setter拆分为单独的界面,可以使用C#template co-variance功能:
public interface IReadModel<out T>
{
T Data {get;}
string Info { get; }
}
public interface IWriteModel<in T>
{
T Data { set; }
string Info { set; }
}
public class SecureModel<T> : IReadModel<T>, IWriteModel<T>
{
public string Info { get; set; }
public T Data { get; set; }
}
class Program
{
static void Main(string[] args)
{
var m = new SecureModel<string>();
m.Data = "test";
IReadModel<object> genericRead = (IReadModel<object>)m;
Console.WriteLine(genericRead.Data);
}
}