I have an object that’s being automatically serialized by the WebAPI, but I wanted to wrap it to provide context to my data. An example would be:
public class SecureModel<T>
{
public string Info { get; set; }
public T Data { get; set; }
}
This serializes/deserializes no problem with my JSON requests and all is well. However, I want to verify some of that Info before I allow the request to finish executing, so I’ve added an ActionFilter where I’m retrieving parameters of my 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.
}
}
When I examine the argument, it’s exactly what I need, however I can’t figure out how to weakly type it to SecureModel without specifying the actual generic type. I feel like I should be able to case this to SecureModel<object> and properly access the root, however it does not allow that. So far, I can only get the data I need using:
var notStrongEnough = arg.GetType().GetProperty("Info");
However, I’d prefer not to use Reflection for this and I am having a hard time moving forward without an answer. My alternative in this situation would be to change Data to a string and serialize/deserialize the JSON object manually, but that defeats some of the purpose of using Web API over MVC3.
Note: Changing the design to have SecureModel as the base class adds challenges to some of the hashing I am performing on the data, so I’d prefer to not go down that path either.
Thanks!
Edit: Misphrased title.
The typical solution to this sort of problem in C# is to create non-generic interfaces that your generic types implement. For example, with your class:
You could define an interface,
ISecureModel:And now you can implement it in your data class:
We use explicit interface implementation here since the non-generic (
object) and generic (T) versions of propertyDatawould otherwise collide.Now, to get the info, you can simply cast to
ISecureModel.