visual-studioautomationblazorpublishing

Change base path on VS publish


I have a blazorWASM project. While developing, I need index.html to have it's base path set to <base href="/" />, but when I use the built-in publish to file, the output is set to land directly into my PHP project which acts as a host that serves WASM static files, and needs this base path: <base href="/wwwroot/" />.

Is there a way to have them automatically switched so I do not keep forgetting to do so? Alternatively, how do I configure the project so that it will work while I debug it on IIS with the wwwroot base path?


Solution

  • You need to add a build task to your CSPROJ Blazor WASM.

    Important note: you need Newtonsoft 13.0.1, System.Text.Json isn't supported.

    <UsingTask TaskName="ReplaceBaseHRef" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
        <ParameterGroup>
            <InputFilename ParameterType="System.String" Required="true" />
            <AppSettingsfile ParameterType="System.String" Required="true" />
            <BaseHRefAttribute ParameterType="System.String" Required="true" />
        </ParameterGroup>
        <Task>
            <Reference Include="$(NugetPackageRoot)\newtonsoft.json\13.0.1\lib\netstandard2.0\Newtonsoft.Json.dll" />
            <Using Namespace="System" />
            <Using Namespace="System.IO" />
            <Using Namespace="System.Text" />
            <Using Namespace="System.Text.RegularExpressions" />
            <Using Namespace="Newtonsoft.Json" />
            <Using Namespace="Newtonsoft.Json.Linq" />
            <Code Type="Fragment" Language="C#">
                <![CDATA[  
                      var inputFile = File.ReadAllText(InputFilename);                
              var appsetting = File.ReadAllText(AppSettingsfile);
    
                        JObject appsettings = JObject.Parse(appsetting);
    
              var baseHRef = appsettings[BaseHRefAttribute].Value<string>();
              if (!string.IsNullOrEmpty(baseHRef)) {
                        Log.LogMessage( MessageImportance.High, baseHRef );
    
                          var outputFile = InputFilename;
                          var matchExpression = "\\<base\\ href=\\\"(.*)\\\"\\ \\/\\>";
                var newBaseHRef = $"<base href=\"{baseHRef}\" />";
                File.WriteAllText(
                  outputFile,
                  Regex.Replace(inputFile, matchExpression, newBaseHRef)
                  );
              }
            ]]>
            </Code>
        </Task>
    </UsingTask>
    
    <Target Name="ReplaceBaseHRef" AfterTargets="Publish">
        <ReplaceBaseHRef InputFilename="$(PublishDir)wwwroot\index.html" AppSettingsfile="$(PublishDir)wwwroot\appsettings.Production.json" BaseHRefAttribute="BaseHRef" />
    </Target>
    

    Now take your appsettings.Production.json and add the configuration setting as:

    {
      "BaseHRef": "/client/",
      ...
    }
    

    now launch the Publish (in folder, IIS or on Azure).

    Your index.html will contain <base href="/client/" />.