通用 Web Api 方法 [英] Generic Web Api method

查看:20
本文介绍了通用 Web Api 方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些类,例如 CustomerModelCustomerDetailsModel,它们是从 ModelBase 继承而来的.

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

我也不想为每个模型类型引入子类.

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

在一种情况下,有一个 foreach 的 post 方法.

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

我想实现一个通用的 web api 方法,比如

I want to implement a generic web api method like

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

如果我只是创建一个泛型方法,我会得到一个异常,它告诉我 web api 方法不能有泛型方法.但是前段时间我看到了一个使用 web api v1 的实现,它使用某种自定义查找机制来处理这个问题.但我已经想不通了.

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.

作为一种解决方法,我创建了一个 callwrapper 来确定类型并调用内部通用方法,但这感觉很丑

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

谁能告诉我如何实现 GenericWebAPiMethod?

Can anyone tell me how to implement that GenericWebAPiMethod?

推荐答案

这种方法的问题在于 Web API 不知道如何反序列化对象.

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 { }

您可以编写一个通用控制器来处理从 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>
{
}

这篇关于通用 Web Api 方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆