我正在使用 WebAPI 2.2 和 Microsoft.AspNet.OData 5.7.0 创建支持分页的 OData 服务。
当托管在生产环境中时,WebAPI 存在于未暴露在外部的服务器上,因此 OData 响应中返回的各种链接,例如@odata.context
和@odata.nextLink
指向内部 IP 地址http://192.168.X.X/<AccountName>/api/...
等。
我已经能够Request.ODataProperties().NextLink
通过在每个 ODataController 方法中实现一些逻辑来用外部 URL 替换内部 URL来修改https://account-name.domain.com/api/...
,但这非常不方便,它只修复了 NextLinks。
有没有办法在配置 OData 服务时设置外部主机名?我看到了一个属性Request.ODataProperties().Path
,想知道是否可以在config.MapODataServiceRoute("odata", "odata", GetModel());
调用时设置基本路径,或者在GetModel()
实现中使用例如ODataConventionModelBuilder
?
更新:到目前为止,我想出的最佳解决方案是创建一个BaseODataController
覆盖该Initialize
方法并检查是否Request.RequestUri.Host.StartsWith("beginning-of-known-internal-IP-address")
然后像这样进行 RequestUri 重写:
var externalAddress = ConfigClient.Get().ExternalAddress; // e.g. https://account-name.domain.com
var account = ConfigClient.Get().Id; // e.g. AccountName
var uriToReplace = new Uri(new Uri("http://" + Request.RequestUri.Host), account);
string originalUri = Request.RequestUri.AbsoluteUri;
Request.RequestUri = new Uri(Request.RequestUri.AbsoluteUri.Replace(uriToReplace.AbsoluteUri, externalAddress));
string newUri = Request.RequestUri.AbsoluteUri;
this.GetLogger().Info($"Request URI was rewritten from {originalUri} to {newUri}");
这完美地修复了@odata.nextLink
所有控制器的 URL,但由于某种原因,@odata.context
URL 仍然得到AccountName
部分(例如https://account-name.domain.com/AccountName/api/odata/$metadata#ControllerName)所以它们仍然没有工作。