通用Web Api方法

Boa*_*ler 7 c# generics asp.net-web-api asp.net-web-api-routing asp.net-web-api2

我有一些类似CustomerModelCustomerDetailsModel正在进行的课程ModelBase.

另外,我不想为每个模型类型引入子类.

在一个案例中有一个post方法foreach.

所以我可以手动创建多个路由来调用看起来像的方法

Handle<T>(T model) where T : ModelBase
Run Code Online (Sandbox Code Playgroud)

它们只在所谓的路径上有所不同.例如:

baseurl/api/customer => CustomerModel
baseurl/api/customerdetails => CustomerDetailsModel
Run Code Online (Sandbox Code Playgroud)

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

[HttpPost]
void Post<T>(T model) where T : ModelBase
Run Code Online (Sandbox Code Playgroud)

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

作为一种解决方法,我创建了一个callwrapper来确定类型并调用内部泛型方法,但这感觉非常难看

 public async Task<IHttpActionResult> Post(string id, string moduleType)
        {
            await AsyncGenericCallWrapper(moduleType);
...
Run Code Online (Sandbox Code Playgroud)

拥有上面提到的通用控制器会有很多不足之处.

  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;
        }
Run Code Online (Sandbox Code Playgroud)

我可以想象有一个自定义属性来映射类型

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

有了这个,我可以为每个属性创建路由,但现在仍然可以调用该方法,因为它是通用的,我也不知道如何干扰反序列化机制

谁能告诉我如何实现GenericWebAPiMethod?

Tho*_*mas 10

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

您可以创建通用控制器,而不是使用通用方法.

假设您的模型是这样的:

public abstract class ModelBase{ }

public class CustomerModel : ModelBase {}

public class CustomerDetailsModel: ModelBase { }
Run Code Online (Sandbox Code Playgroud)

您可以编写一个通用控制器来处理从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>
{
}
Run Code Online (Sandbox Code Playgroud)