7

I've some classes like CustomerModel or CustomerDetailsModel which are inherting from ModelBase.

Also i don't want to introduce subclasses for each modeltype.

In one case have a post method foreach.

So i could manually create multiple routes to call a method which looks like

Handle<T>(T model) where T : ModelBase

They only differ in the path the were called. For example:

baseurl/api/customer => CustomerModel
baseurl/api/customerdetails => CustomerDetailsModel

I want to implement a generic web api method like

[HttpPost]
void Post<T>(T model) where T : ModelBase

If I simply create a generic method i got an exception which tells me that the web api method could not have generic methods. But sometime ago I've seen an implementation with web api v1 using some kind of custom lookup mechanisms to handle this. But i can't figure out it anymore.

As a workaround I created a callwrapper which determines the type and invokes a internal generic method, but this feels quite ugly

 public async Task<IHttpActionResult> Post(string id, string moduleType)
        {
            await AsyncGenericCallWrapper(moduleType);
...

It would be much butter to have the above mentioned generic controllerr.

  private async Task AsyncGenericCallWrapper(string moduleType)
        {
            Type type = GetModuleType(moduleType);
            var content = await Request.Content.ReadAsStringAsync();
            var instance = JsonConvert.DeserializeObject(content, type);

            MethodInfo method = this.GetType().GetMethod("InternalGenericMethod", BindingFlags.NonPublic | BindingFlags.Instance);
            MethodInfo generic = method.MakeGenericMethod(type);
            var result = generic.Invoke(this, new object[] { instance }) as Task;

            await result;
        }

I can image to have a custom Attribute which maps the types like

[GenericRoute("/customer", typeof(CustomerModel)]
[GenericRoute("/customerDetail", typeof(CustomerDetailModel)]
void Post<T>(T model) where T : ModelBase

With this i could create routes for each attribute, but still the method now get invoked as it is generic , nor i know how to interfer the deserialization mechanism

Can anyone tell me how to implement that GenericWebAPiMethod?

2
  • These answers seem to indicate that it may be possible but it makes things more complicated than just subclassing. Commented Apr 1, 2015 at 18:50
  • i know, but having subclasses wouldn't help in my scenario. As i want to have it dynamically extended without redeploying the webpage. New models are possible during the runtime Commented Apr 1, 2015 at 18:52

1 Answer 1

13

The problem with this approach is that the Web API does not know how to deserialize the object.

Rather than having a generic method, you can create a generic controller.

Let's say your model is like that:

public abstract class ModelBase{ }

public class CustomerModel : ModelBase {}

public class CustomerDetailsModel: ModelBase { }

You can write a generic controller to deal with classes that inherits from ModelBase :

public class ModelBaseController<T> : ApiController where T : ModelBase 
{
    [HttpPost]
    public void Post(T model)
    {
        ...
    }
}

public class CustomerModelController : ModelBaseController<CustomerModel>
{
}

public class CustomerDetailsModelController : ModelBaseController<CustomerDetailsModel>
{
}
Sign up to request clarification or add additional context in comments.

1 Comment

For extra fun, you can also get fancy with mvcBuilder.ConfigureApplicationPartManager and use your ModelBaseController<T> a bit more directly

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.