.net-coreasp.net-core-mvcms-yarp

Yarp forwarding settings to dynamically forward


We have a setup where we have one IIS Site per customer and each site runs the same code.

We're looking to use the streangling fig to update our C# ASP.NET Core MVC app, and so we need to use yarp. Since it is one codebase deployed multiple times, we cannot have the appsettings.json be unique per site.

What we would like it to have our ASP.NET Core MVC site be customername.productname.com and our classic ASP.NET MVC site be customername.productname.com.local. Is there a way we're able to just append .local to the host in this mapping so that each site can easily be mapped to it's corresponding legacy site?

An example of what we're looking to achieve:

"ReverseProxy": {
    "Routes": {
      "route1": {
        "ClusterId": "cluster1",
        "Match": {
          "Path": "{**catch-all}"
        }
      }
    },
    "Clusters": {
      "cluster1": {
        "Destinations": {
          "destination1": {
            "Address": "<theoriginalhost>.local"
          }
        }
      }
    }
  }

Solution

  • you could try this code:

    using Microsoft.AspNetCore.Builder;
       using Microsoft.AspNetCore.Hosting;
       using Microsoft.Extensions.DependencyInjection;
       using Microsoft.Extensions.Hosting;
       using Yarp.ReverseProxy.Configuration;
       using Yarp.ReverseProxy.Transforms;
    
       public class Startup
       {
           public void ConfigureServices(IServiceCollection services)
           {
               services.AddReverseProxy()
                   .LoadFromMemory(GetRoutes(), GetClusters())
                   .AddTransforms(transformBuilderContext =>
                   {
                       transformBuilderContext.AddRequestTransform(async transformContext =>
                       {
                           // Get the original host
                           var originalHost = transformContext.HttpContext.Request.Host.Host;
    
                           // Check if it's a request to the legacy site
                           if (originalHost.EndsWith(".local"))
                           {
                               var newHost = originalHost.Replace(".local", "");
                               var newUri = new Uri($"{transformContext.DestinationAddress.Scheme}://{newHost}{transformContext.DestinationAddress.PathAndQuery}");
                               transformContext.ProxyRequest.RequestUri = newUri;
                           }
                           else
                           {
                               var newHost = originalHost + ".local";
                               var newUri = new Uri($"{transformContext.DestinationAddress.Scheme}://{newHost}{transformContext.DestinationAddress.PathAndQuery}");
                               transformContext.ProxyRequest.RequestUri = newUri;
                           }
                       });
                   });
           }
    
           public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
           {
               if (env.IsDevelopment())
               {
                   app.UseDeveloperExceptionPage();
               }
    
               app.UseRouting();
               app.UseEndpoints(endpoints =>
               {
                   endpoints.MapReverseProxy();
               });
           }
    
           private static RouteConfig[] GetRoutes()
           {
               return new[]
               {
                   new RouteConfig
                   {
                       RouteId = "route1",
                       ClusterId = "cluster1",
                       Match = new RouteMatch
                       {
                           Path = "{**catch-all}"
                       }
                   }
               };
           }
    
           private static ClusterConfig[] GetClusters()
           {
               return new[]
               {
                   new ClusterConfig
                   {
                       ClusterId = "cluster1",
                       Destinations = new Dictionary<string, DestinationConfig>
                       {
                           {
                               "destination1",
                               new DestinationConfig
                               {
                                   Address = "http://placeholder" // Placeholder, will be transformed dynamically
                               }
                           }
                       }
                   }
               };
           }
       }