从另一个Web API控制器直接调用另一个Web API控制器

12
给定一个控制器Proxy和一个名为GetInformation的操作。 我想要能够调用Users控制器中的GetInformation方法。这两个WebAPI控制器在同一个项目中,但是直接调用会导致循环引用问题。
var controller = new UsersController();
return controller.GetInformation(request);

无法正常工作。

签名为:

public HttpResponseMessage GetInformation(InformationRequest request)

我不想进行完整的重定向响应,因为我不想将UserController路由暴露在外部。这需要是一个仅限内部调用。


4
为什么直接调用不行?你收到了错误吗?虽然感觉如果你有一个内部层可以调用而不是另一个控制器会更好。 - juunas
不必调用控制器,您可以使用RedirectToRoute(或)将GetInformation的功能移动到服务中并调用该服务。 - sam
@sam - RedirectToRoute 返回一个 ActionResponse 并暴露重定向到客户端。这是不可取的(并且也在问题陈述中提到)。 - VulgarBinary
@juunas - 无论HttpResponseMessage是什么,构建HttpResponseMessage时都会引发空引用异常。我在下面的答案中发布了解决方法,构建控制器方法所需的一些核心部件缺失。显然这些是由WebAPI(MVC)引擎注入的,没有它们就无法生成HttpResponses。 - VulgarBinary
3个回答

8
如想在不同的控制器中解决这个API到API方法的问题,我们已经找到了一个可行的解决方案。最初的尝试已经接近成功,只差了一些细节。
var controller = new UserAccountController
{
   Request = new HttpRequestMessage(HttpMethod.Post, Request.RequestUri.AbsoluteUri.Replace("/current/route", "/route/to_call"))
};
controller.Request.Properties[HttpPropertyKeys.HttpConfigurationKey] = new HttpConfiguration();
return controller.GetInformation(request);

这样做可以构建目标控制器并直接调用所需的方法。最大的复杂性在于Uri的调整。


1
也许你可以创建一个帮助类/方法来处理这个逻辑的共同部分,并尝试将URI替换移动到配置文件中,并在帮助程序中使用这些值。 - Mauricio Gracia Gutierrez

3
您应该在您的 UsersController 中执行类似以下的操作。
public HttpResponseMessage GetInformation(InformationRequest request)
{
    HttpResponseMessage resp ;

    resp = UserBusinessLogic.GetInformation(request) ;

    return resp ;
}

从您的ProxyController中,您可以重用“UserBusinessLogic”方法来使用相同的代码片段获取相同的信息。


2
是的,那是“理想”的解决方法。然而,我们需要对它进行的操作量不现实,无法更改所有控制器中的逻辑来处理这种方法。你提供了一种架构转变,如果我从头开始构建它,那肯定是完美的(也是我不会在Stack上发布的内容)。不幸的是,这不是一个可行的选择。 - VulgarBinary

0

另一种方法可以是:

IQueryable<Users> GetInformation()

不使用IHttpActionResult返回类型。您的方法仍将保持为Http GET方法,然后像调用任何类方法一样调用它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接