I'm using WebAPI 2.2 and Microsoft.AspNet.OData 5.7.0 to create an OData service that supports paging.
When hosted in the production environment, the WebAPI lives on a server that is not exposed externally, hence the various links returned in the OData response such as the @odata.context
and @odata.nextLink
point to the internal IP address e.g. http://192.168.X.X/<AccountName>/api/...
etc.
I've been able to modify the Request.ODataProperties().NextLink
by implementing some logic in each and every ODataController method to replace the internal URL with an external URL like https://account-name.domain.com/api/...
, but this is very inconvenient and it only fixes the NextLinks.
Is there some way to set an external host name at configuration time of the OData service? I've seen a property Request.ODataProperties().Path
and wonder if it's possible to set a base path at the config.MapODataServiceRoute("odata", "odata", GetModel());
call, or in the GetModel()
implementation using for instance the ODataConventionModelBuilder
?
UPDATE: The best solution I've come up with so far, is to create a BaseODataController
that overrides the Initialize
method and checks whether the Request.RequestUri.Host.StartsWith("beginning-of-known-internal-IP-address")
and then do a RequestUri rewrite like so:
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}");
This perfectly fixes the @odata.nextLink
URLs for all controllers, but for some reason the @odata.context
URLs still get the AccountName
part (e.g. https://account-name.domain.com/AccountName/api/odata/$metadata#ControllerName) so they still don't work.