Skip to main content

Posts

Showing posts with the label Razor

Safely injecting a JSON configuration object into a Razor Page

While reviewing an ASP.NET Core Razor page application that needed to share server-side configuration with client-side JavaScript, I noticed the following approach to inject a JSON object: <script> var featureFlags= @Html.Raw(Model.FeatureFlagsJson); </script> It works — until it doesn't. This post walks through the right way to do it, why the naive approach can blow up in your face, and what the production-safe pattern looks like. Remark: There was a mistake in the original version of this post. I updated it with a fixed version of the code Why the naive approach is dangerous Directly interpolating server-side values into a <script> block creates an XSS (Cross-Site Scripting) vector . If any value in your config object contains characters like </script> , " , or ' , the browser can interpret that as the end of your script tag — or worse, execute attacker-controlled code. Consider this innocent-looking config value: public string ...

dotnet pack issue–files without extension

To share components, layout and some general CSS and javascript between ASP.NET Core MVC projects, we are using a Razor Class Library. This Razor Class library is packaged as a NuGet package and uploaded to Azure Artifacts. One of the libraries we share using this approach is Bootstrap. Similar to other open source projects, Bootstrap has an extensionless LICENSE file explaining the exact license agreements. When you package this project using dotnet pack , the extensionless LICENSE file is transformed into a ‘LICENSE’ folder container the ‘LICENSE’ file: I have no idea why this happens but OK it works…until the moment I added this NuGet package as a dependency to another project. When I try to publish this project (using dotnet publish ) it fails with the following error message: Error MSB3025: The source file "C:\Program Files\dotnet\sdk\6.0.101\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(237,5): C:\Users\tfsservice\packages\vlm.sofacore.web.huisstij...

Share reusable UI components through a Razor class library

One ASP.NET Core feature that I really like and most people are not aware of it existence are Razor Class libraries (RCL). With RCL you can package Razor views, pages, Razor components and view components and reuse them in different applications. I blogged about RCL before and although I really like the feature I got feedback from my development teams that the behavior was not consistent and they sometimes couldn’t get it working. I never had time to really investigate the root cause until now. So this blog post is here to explain my findings. The development environment First of all it is important to understand that the behavior of RCL is different in Development compared to other environments. When running the app that uses the RCL from build output ( dotnet run ), static web assets are enabled that allow ASP.NET Core to load static web assets from locations outside the wwwroot. This is required because ASP.NET Core will load the assets directly from the RCL NuGet location....

Visual Studio 17.5 - ViewComponents are broken

On our last architecture board, one of the architects shared the following problem. After upgrading to Visual Studio 17.5 Razor ViewComponents were no longer rendered. Instead the viewcomponent tag remained on the page. *UPDATE: In the meanwhile Visual Studio 2022 version 17.5.2 got released which contains a fix for the issue I'm explaining below* This problem manifested not only on the local developer machine but also on the build server after upgrading the Visual Studio Build tools to 17.5.  The root cause is a bug in the latest dotnet runtimes that are installed as part of the Visual Studio upgrade. It affects the following dotnet runtimes  6.0.14 and 7.0.3 that match with this SDK version: 6.0.114, 6.0.309, 6.0.406 for .Net 6 and 7.0.103, 7.0.200 and 7.0.201 for .Net 7. As a workaround we included an extra build step in our yaml pipeline that uses a non affected SDK version: Of course this would require all our teams to update their projects. So what we did instead...

Razor Class Libraries–Static Content 404 issue –Part 2

I’ll continue my journey using Razor Class Libraries in ASP.NET Core. Here are my previous posts: ASP.NET Core – Razor Class Libraries Razor Class Libraries -  Views not found Razor Class Libraries – Static Content Razor Class Libraries – Clean up your Content path Razor Class Libraries -  Static Content 404 issue – Part 1 After a first colleague returned to his desk with a solution for the problem I discussed yesterday , a second colleague arrived and explained he had a similar problem. This time I could pinpoint the issue to the following PackageReference that was (still) used in a referenced project: <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" /> Static files worked differently in .NET Core 2.2 Razor Class Libraries. The inclusion of the Microsoft.AspNetCore.Mvc v2.2.0 library broke the behaviour in ASP.NET Core 3.x applications. This reference is no longer needed as it is now a part of the...

Razor Class Libraries–Static Content 404 issue –Part 1

I’ll continue my journey using Razor Class Libraries in ASP.NET Core. Here are my previous posts: ASP.NET Core – Razor Class Libraries Razor Class Libraries -  Views not found Razor Class Libraries – Static Content Razor Class Libraries – Clean up your Content path Today I want to share an issue a colleague got when he tried to use a Razor Class Library I created. When he tried to load a static asset from the RCL, the asset was not found and a 404 error was returned to the browser. It took me a while to pinpoint the issue but in the end it turned out that the following setting in his ASP.NET Core project caused the problem: <ANCMPreConfiguredForIIS>true</ANCMPreconfiguredForIIS> After commenting out this line in the csproj file, the static assets were loaded correctly I have no clue why this solved the problem as I don’t see any relation between these features…

Razor Class libraries–Clean up your content path

I’ll continue my journey using Razor Class Libraries in ASP.NET Core. Here are my previous posts: ASP.NET Core – Razor Class Libraries Razor Class Libraries -  Views not found Razor Class Libraries – Static Content Today I want to write a small addition to my post from yesterday. As I mentioned yesterday to reference some content inside your razor views you need to use a path similar to _content/{LIBRARY NAME}. This path doesn’t look so nice. Luckily you change it to a different path name by editing the RCL project properties and adding a StaticWebAssetBasePath . Now you can access your files using /myownpath/example.css .

Razor Class Libraries–Static Content

I’ll continue my journey using Razor Class Libraries in ASP.NET Core. Here are my previous posts: ASP.NET Core – Razor Class Libraries Razor Class Libraries -  Views not found Today I want to cover how you can use static content inside your Razor Class library. To include static content(images, fonts, stylesheets,…) in your RCL you need to create a wwwroot folder in the class library and include any required files there: When packing an RCL, all content in the wwwroot folder is automatically included in the package. As this content becomes part of the DLL you cannot just reference them from the root path(“~”. Instead the path is constructed using ‘_content/{LIBRARY NAME}/’. For example to reference an example.css file that you stored inside a RCL named ‘Example.RCL’, the correct way to include this css file in your application becomes:

ASP.NET Core–Razor Class Libraries

A little known feature in ASP.NET Core (MVC/Razor pages) is the support for Razor Class libraries(RCL).  Through the RCL you can package and reuse UI components like View Components or Razor Components but also share full feature areas containing Razor view, controllers, models and so on… Let’s get started Open Visual Studio and choose Create a new project . Select Razor Class Library and click Next . Give the library a name and click on Create . Remark 1: To avoid a file name collision with the generated view library, ensure the library name doesn't end in .Views . Remark 2: Select Support pages and views if you need to support views. Otherwise only Razor components are supported. Now you can start adding your View Components and Razor components to your RCL. When building your RCL 2 DLL’s are created: One DLL containing all your logic One DLL containing your Razor views (ends with .Views ) You can now either reference this...

Razor compilation

In .NET Core (3.x) Razor compilation happens by default at build time. This means that every time you make a change to a Razor file, you have to rebuild your application before a change becomes visible inside your frontend. This is different compared to .NET where Razor compilation happened at runtime. If you have to work a lot inside Razor, build time compilation can be annoying and slow down your development process. Luckily it is possible to enable runtime compilation for your ASP.NET Core Web application. One option you have is to enable runtime compilation at project creation: Create a new ASP.NET Core Web application in Visual Studio Check the Enable Razor runtime compilation check box when creating your project. If you have an existing project, you have to take a different approach: First install the Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation NuGet package. Update the project's Startup.ConfigureServices method to include a call...

ASP.NET Core–Using Value Tuples in Razor

I was wondering if it was possible to use ValueTuples as your Razor model. This turned out to work perfectly! Here is my ViewComponent method(notice that this also works in Razor pages and MVC controllers): And here is my Razor view:

ASP.NET MVC–Precompile Razor views on Release build

Last week I was investigating slow startup times of an ASP.NET MVC web application. We were able to trace the root cause to a really complex Razor page. This was the first page that was loaded and takes a long time to compile. By default Razor compilation happens the first time a Razor page is requested by the browser. However you can change this and prebuild all the Razor pages by adding the MvcBuildViews tag to your .csproj file: <?xml version="1.0" encoding="utf-8"?> <Project> <PropertyGroup> <MvcBuildViews>true</MvcBuildViews> Unfortunately it had a large impact on the build times making debugging a pain for the developers. So in the end we decided to only precompile Razor on a release build. Therefore we had to add 2 MvcBuildViews tags with a condition: <MvcBuildViews Condition="'$(Configuration)'=='Debug'">false</MvcBuildViews> <MvcBuildViews ...