Open BenjaminCharlton opened 3 years ago
Thanks for your feedback. Blazor WebAssembly currently does not support web.config transform. We'll consider this an enhancement for the backlog. For the time being, we would recommend using a custom web.config. The default contents for the web.config that Blazor adds (using the output you get from publishing the app).
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.
Were you ever able to get a web.config that allows you to still run locally?
For a stand-alone Blazor WASM project, you should be able to do this at build time (rather than at publish time) if you use the SlowCheetah library as described on the accepted answer on my StackOverflow question.
But, if your project uses Blazor WASM with pre-compilation on the server (as described here), as mine now does, then I still haven't yet found the solution, and would love to know.
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.
As a workaround for adding the blazor-environment
header. You can add a file called Directory.build.targets
in the blazor project, with the content:
<Project>
<UsingTask
TaskName="AddBlazorEnvironment"
TaskFactory="RoslynCodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" >
<ParameterGroup>
<Template ParameterType="System.String" Required="true" />
<Target ParameterType="System.String" Required="true" />
<Environment ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Reference Include="$(OutputPath)System.Xml.XDocument.dll" />
<Using Namespace="System.Xml.Linq" />
<Code Type="Fragment" Language="CS">
<![CDATA[
XElement GetOrAdd(XElement elem, string name) {
var child = elem.Element(name);
if (child == null) {
elem.Add(child = new XElement(name));
}
return child;
}
var doc = XDocument.Load(Template);
var elem = doc.Root;
elem = GetOrAdd(elem, "system.webServer");
elem = GetOrAdd(elem, "httpProtocol");
elem = GetOrAdd(elem, "customHeaders");
const string HEADER_NAME = "blazor-environment";
var add = elem
.Elements("add")
.FirstOrDefault(e => e.Attribute("name")?.Value == HEADER_NAME);
if (add == null) {
elem.Add(add = new XElement("add",
new XAttribute("name", HEADER_NAME)
));
}
add.SetAttributeValue("value", Environment);
doc.Save(Target);
]]>
</Code>
</Task>
</UsingTask>
<Target Name="TrasformBlazorWebConfigFile"
AfterTargets="_AddBlazorWebConfigFile">
<ItemGroup>
<BlazorTemplateWebConfig Include="@(ResolvedFileToPublish)" Condition=" '%(Filename)%(Extension)' == 'BlazorWasm.web.config' " />
<BlazorTransformedWebConfig Include="@(BlazorTemplateWebConfig->'$(IntermediateOutputPath)web.config')" />
</ItemGroup>
<AddBlazorEnvironment
Condition="'@(BlazorTemplateWebConfig)' != ''"
Template="@(BlazorTemplateWebConfig)"
Target="@(BlazorTransformedWebConfig)"
Environment="$(EnvironmentName)"
/>
<ItemGroup Condition="'@(BlazorTemplateWebConfig)' != ''">
<ResolvedFileToPublish Remove="@(BlazorTemplateWebConfig)" />
<ResolvedFileToPublish
Include="@(BlazorTransformedWebConfig)"
ExcludeFromSingleFile="true"
CopyToPublishDirectory="PreserveNewest"
RelativePath="web.config" />
</ItemGroup>
</Target>
</Project>
It assumes you don't have an existing web.config
file, and intercepts the creation of the default one.
Holy moley, Markus, this looks perfect! I haven't yet had time to test it out but I shall give it a try as soon as I can.
Thank you very much for thinking of me!
@MizardX I tried this solution but not sure how to inject that Environment
param
The "AddBlazorEnvironment" task was not given a value for the required parameter "Environment".
Is there any movement on the transformation file approach?
@ajamrozek
@MizardX I tried this solution but not sure how to inject that
Environment
paramThe "AddBlazorEnvironment" task was not given a value for the required parameter "Environment".
Is there any movement on the transformation file approach?
You can add the parameter -p:EnvironmentName=Development
to the arguments when building or publishing. When building in Visual Studio, it should get added automatically.
There should be some kind of publish error if this is not supported. Huge time waster.
It is unfortunate that it is not compatible, year 2024 and it still does not work....
Describe the bug
I'm not 100% sure if this is a problem with Visual Studio's publishing wizard, or a problem with Blazor, or just something that I did wrong.
I asked on StackOverflow and learned some useful things from the community but we have not solved the problem so far.
Summary I want to apply a
web.config
transformation when publishing my Blazor WebAssembly application to my Staging and Production environments via FTP using the Visual Studio Publish Wizard, as described hereI want the transformation to add a custom header containing the blazor-environment variable as documented here
Naturally, I don't want the addition of a
web.config
file to break my local development environment either (I've noticed that's exactly what happens if you just paste the auto-generatedweb.config
from the production/staging environment into the project root).No matter what I try, my
web.config
transformations don't get applied when I publish the site, and publishing takes an hour each time, so progress is slow!To Reproduce
You can view a minimal reproducible sample here, or follow the steps below. 1) Create a new Blazor WebAssembly project. 2) Edit
Index.razor
so it looks like this:3) In configuration manager: i) Rename "Debug" to "Development" ii) Rename "Release" to "Production" ii) Add a new configuration called "Staging", based on "Production" 4) Right click on your project in Solution Explorer > Add new item > Add a
web.config
file. The default one is mostly blank, except for the XML declaration, a comment, a pair of configuration tags. Leave it alone because, in my experience, adding anything to it breaks the project when debugging locally. Check that your project still builds and runs locally. It should. 5) Right click on your project and select "Publish". 6) Add a new FTP publish profile called "Staging" and save some details of an FTP server you can use as a staging environment. Specify the configuration "Staging" for this profile. Don't publish yet; just save the profile. Mine looks like this:7) Add a new FTP publish profile called "Production" and save some details of an FTP server you can use as a production environment. Specify the configuration "Production" for this profile. Don't publish yet; just save the profile. Mine looks like this:
8) Right click on each of the new
.pubxml
profiles in turn and choose "Add config transform". You should now have aweb.Staging.config
and aweb.Production.config
with some boilerplate code. 9) Paste this intoweb.Staging.config
:10) Paste this into
web.Production.config
:11) Publish the Blazor application using each of the profiles "Production" and "Staging".
What I hoped would happen
web.config
file published at each site should have been transformed to contain the newcustomHeader
with an appropriate value forblazor-environment
. I would expect other transformations to have been applied by the publishing wizard to make Blazor run on IIS (usually, for example, it adds<staticContent><mimeMap>
and<httpCompression><dynamicTypes>
and other nice stuff like that).web.config
(whether successful or failed).What actually happened
web.config
at all, so running the site produces a 403 error.web.config
.Something else I tried that didn't work
I have also tried the above steps but with a complete
web.config
file in the project root (I got the content off a Blazor WASM application that was published to IIS. This prevents the project running at all in the development environment but it does at least run in Production and Staging. Still, though, no transformations got applied toweb.config
so the home page says "Environment: Production" in both Production and Staging environments.