Web API 通用操作

2024-04-25

我有一个 http 操作,需要采用两个不同的对象模型。实现查看两个模型对象并知道此时要做什么。我可以使用通用对象吗?

[HttpPost]
public IHttpActionResult InsertData(string accessKey, [FromBody] T content)
{
    try
    {
        MobileAppService ms = new MobileAppService();
        ResultStatus resultStatus = ms.ProcessAppLogging(t);
        return Ok(resultStatus.ResultCode);
    }
    catch (Exception e)
    {
        Elmah.ErrorSignal.FromCurrentContext().Raise(e);
    }
}

具有通用操作方法的控制器

使用框架的默认实现,不,您不能执行此类操作:

public IHttpActionResult InsertData([FromBody] T model)

这是您收到的异常:

无法在控制器上调用操作方法“XXXX” “XXXX”因为 操作方法是一个通用方法。

但是这个框架是非常可扩展的,如果你很好地理解了ASP.NET Web API 中的路由和操作选择 https://learn.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/routing-and-action-selection?WT.mc_id=DT-MVP-5003235并了解路由、控制器选择、操作选择、参数绑定和操作调用是如何工作的,然后您可以对框架进行一些定制以支持通用操作方法选择和调用。

在您的自定义逻辑中,为了能够在运行时执行操作,您需要解析T在运行时。为此,您可以依靠属性将其限制为某些已知类型,或者您可以依靠一些上下文信息,例如路由数据、标头值、一些特殊值,例如$type在身体等等。

提供自定义实现来处理通用操作方法对于本文来说太宽泛了。也就是说,让我分享其他解决方案。

从通用基础控制器派生

您可以拥有一个基本通用控制器,然后拥有两个从基本控制器派生的非通用控制器,并通过在基本控制器中实现的单个方法处理请求。我假设你已经看到了这个帖子 https://stackoverflow.com/a/36413607/3110834它已经提出了相同的解决方案:

public class MyBaseController<T> : ApiController
{
    public IHttpActionResult InsertData([FromBody] T model)
    {
        //Write the generic code here, for example:
        dbContext.Set<T>().Add(model);
        dbContext.SaveChanges();
        return some value;            
    }
}

Then:

public class ProductController : MyBaseController<Product> { }
public class CustomerController : MyBaseController<Customer> { }

Rely on dynamic并稍后根据上下文信息解析类型

另一种选择是具有以下操作方法:

public IHttpActionResult InsertData([FromBody] dynamic model)

然后基于一些上下文信息,如路由值、标头值、一些特殊值,如$type在正文等中,您可以解析模型类型并调用您的私有泛型方法:

public IHttpActionResult InsertData([FromBody] dynamic model)
{
    Type t = resolve type base on context information
    object data = create an instance of t base on the model values;

    var method = this.GetType().GetMethod(nameof(InsertDataPrivate),
        BindingFlags.NonPublic | BindingFlags.Instance);
    var result = (int)method.MakeGenericMethod(t)
       .Invoke(this, new object[] { data });

    return Ok(result);
}
private int InsertDataPrivate<T>(T model) where T
{
    //Write the generic code here, for example:
    dbContext.Set<T>().Add(model);
    dbContext.SaveChanges();
    return some value;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Web API 通用操作 的相关文章

随机推荐