asp.net – 覆盖webapi odata链接的主机

前端之家收集整理的这篇文章主要介绍了asp.net – 覆盖webapi odata链接的主机前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用WebAPI 2.2和Microsoft.AspNet.OData 5.7.0来创建支持分页的OData服务.

当在生产环境中托管时,WebAPI存在于外部未公开的服务器上,因此OData响应中返回的各种链接(例如@ odata.context和@ odata.nextLink)指向内部IP地址,例如,http://192.168.X.X/\u0026lt; AccountName> / api / …等

我已经能够修改Request.ODataProperties().NextLink,在每个ODataController方法中实现一些逻辑,用一个外部URL替换内部URL,如https://account-name.domain.com/api/. ..,但这非常不方便,只能修复NextLinks.

有没有办法在OData服务的配置时设置外部主机名?我已经看到了一个属性Request.ODataProperties().路径并想知道是否可以在config.MapODataServiceRoute(“odata”,“odata”,GetModel())中设置基本路径;调用,或在GetModel()实现中使用例如ODataConventionModelBuilder?

更新:到目前为止我提出的最佳解决方案是创建一个BaSEODataController来覆盖Initialize方法并检查Request.RequestUri.Host.StartsWith(“begin-of-internal-IP-address”)然后执行RequestUri重写,如下所示:

  1. var externalAddress = ConfigClient.Get().ExternalAddress; // e.g. https://account-name.domain.com
  2. var account = ConfigClient.Get().Id; // e.g. AccountName
  3. var uriToReplace = new Uri(new Uri("http://" + Request.RequestUri.Host),account);
  4. string originalUri = Request.RequestUri.AbsoluteUri;
  5. Request.RequestUri = new Uri(Request.RequestUri.AbsoluteUri.Replace(uriToReplace.AbsoluteUri,externalAddress));
  6. string newUri = Request.RequestUri.AbsoluteUri;
  7. 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),因此它们仍然不起作用.

解决方法

重写RequestUri足以影响@ odata.nextLink值,因为 code that computes the next link直接依赖于RequestUri.其他@ odata.xxx链接是通过 UrlHelper计算的,它以某种方式引用原始请求URI的路径. (因此你在@ odata.context链接中看到的AccountName.我在我的代码中看到过这种行为,但是我无法找到缓存的URI路径的来源.)

我们可以通过创建CustomUrlHelper类来动态重写OData链接,而不是重写RequestUri.新的GetNextPageLink方法将处理@ odata.nextLink重写,而Link方法覆盖将处理所有其他重写.

  1. public class CustomUrlHelper : System.Web.Http.Routing.UrlHelper
  2. {
  3. public CustomUrlHelper(HttpRequestMessage request) : base(request)
  4. { }
  5.  
  6. // Change these strings to suit your specific needs.
  7. private static readonly string ODataRouteName = "ODataRoute"; // Must be the same as used in api config
  8. private static readonly string TargetPrefix = "http://localhost:8080/somePathPrefix";
  9. private static readonly int TargetPrefixLength = TargetPrefix.Length;
  10. private static readonly string ReplacementPrefix = "http://www.contoso.com"; // Do not end with slash
  11.  
  12. // Helper method.
  13. protected string ReplaceTargetPrefix(string link)
  14. {
  15. if (link.StartsWith(TargetPrefix))
  16. {
  17. if (link.Length == TargetPrefixLength)
  18. {
  19. link = ReplacementPrefix;
  20. }
  21. else if (link[TargetPrefixLength] == '/')
  22. {
  23. link = ReplacementPrefix + link.Substring(TargetPrefixLength);
  24. }
  25. }
  26.  
  27. return link;
  28. }
  29.  
  30. public override string Link(string routeName,IDictionary<string,object> routeValues)
  31. {
  32. var link = base.Link(routeName,routeValues);
  33.  
  34. if (routeName == ODataRouteName)
  35. {
  36. link = this.ReplaceTargetPrefix(link);
  37. }
  38.  
  39. return link;
  40. }
  41.  
  42. public Uri GetNextPageLink(int pageSize)
  43. {
  44. return new Uri(this.ReplaceTargetPrefix(this.Request.GetNextPageLink(pageSize).ToString()));
  45. }
  46. }

在基本控制器类的Initialize方法中连接CustomUrlHelper.

  1. public abstract class BaSEODataController : ODataController
  2. {
  3. protected abstract int DefaultPageSize { get; }
  4.  
  5. protected override void Initialize(System.Web.Http.Controllers.HttpControllerContext controllerContext)
  6. {
  7. base.Initialize(controllerContext);
  8.  
  9. var helper = new CustomUrlHelper(controllerContext.Request);
  10. controllerContext.RequestContext.Url = helper;
  11. controllerContext.Request.ODataProperties().NextLink = helper.GetNextPageLink(this.DefaultPageSize);
  12. }

请注意,在给定的控制器类中,页面大小对于所有操作都是相同的.您可以通过将ODataProperties().NextLink的赋值移动到特定操作方法的主体来解决此限制,如下所示:

  1. var helper = this.RequestContext.Url as CustomUrlHelper;
  2. this.Request.ODataProperties().NextLink = helper.GetNextPageLink(otherPageSize);

猜你在找的asp.Net相关文章