Skip to content

Instantly share code, notes, and snippets.

@benjanderson
Created February 2, 2018 21:27
Show Gist options
  • Save benjanderson/412c77eb27593285f1f9b083a1bde724 to your computer and use it in GitHub Desktop.
Save benjanderson/412c77eb27593285f1f9b083a1bde724 to your computer and use it in GitHub Desktop.
Asp.net core 2.1 middleware that changes base href to support IIS virtual directory for SPA applications. Handy for Angular, React, Vue...
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using System.IO;
using System.Text;
using System.Threading.Tasks;
public class ChangeBaseHrefMiddleware
{
RequestDelegate next;
private readonly IConfiguration configuration;
public ChangeBaseHrefMiddleware(RequestDelegate next, IConfiguration configuration)
{
this.next = next;
this.configuration = configuration;
}
public async Task Invoke(HttpContext context)
{
var newContent = string.Empty;
// Store the "pre-modified" response stream.
var existingBody = context.Response.Body;
using (var newBody = new MemoryStream())
{
context.Response.Body = newBody;
await this.next(context);
// Set the stream back to the original.
context.Response.Body = existingBody;
newBody.Seek(0, SeekOrigin.Begin);
// newContent will be `Hello`.
newContent = new StreamReader(newBody).ReadToEnd();
var isHtml = context.Response.ContentType != null && context.Response.ContentType.ToLower().Contains("text/html");
if (isHtml)
{
newContent = newContent.Replace(@"<base href=""/"">", $@"<base href=""{this.configuration["applicationUri"]}"" >");
var encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
context.Response.ContentLength = encoding.GetByteCount(newContent);
}
// Send our modified content to the response body.
await context.Response.WriteAsync(newContent);
}
}
}
// This is mainly geared towards Angular but other spa frameworks can use the same principles
// Make sure you follow the steps outlined in: https://github.com/aspnet/JavaScriptServices/issues/1288#issuecomment-346003334
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// ... configure logic
app.UseStaticFiles();
app.UseSpaStaticFiles();
// This must go after IFileProvider setup
app.UseMiddleware<ChangeBaseHrefMiddleware>();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
}
@smuddy
Copy link

smuddy commented Sep 7, 2020

Thank you. This solution is much smoother then all the stackoverflow answers I read so far.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment