Serve static files in blazor hosted project - c#

It is a pretty simple Task, I want to use images in my razor pages which are located in wwwroot/css/images and use it in html like this.
<img src="~/css/images/logo.png"/>
In a normal ASP.Net Core application I would just add app.UseStaticFiles() in the Configure method, but since this is a blazor hosted application, it changes nothing.
I also tried adding the app.UseStaticFiles() in the server project, but with no success either.
If you want to try it out yourself just create a blazor-hosted project from the templates and try to serve/display images like I did.

Blazor serves static file just fine. The issue you’re having is the syntax you’re using to reference the file. You just need to drop the ~ symbol.
<img src="/css/images/logo.png" />

One precision about that...the static file root for anything
in blazor starts at the wwwroot folder. wwwroot is
simply taken for granted and is omitted in the actual
path you need to use to ask for a static file. using :
"/css/images/logo.png"
could also be expressed :
"css/images/logo.png"..I'm pretty sure.
If you are in a Razor Class Libray...there is also a wwwroot for
the Razor Class Library itself. When used is a Blazor
Wasm Client the filepath for any static file in the RCL becomes :
"_content/[RCL assembly name]/css/images/logo.png"
Note that even for classes and stuff you implement inside the Razor Class Library itself,
even you are in that library defining stuff...static files
in your own wwwroot inside a Razor Class Library are called using
the "_content/[RCL assembly name]" prefix.

Related

Have you ever seen Razor used without MVC in a JavaScript SPA?

I recently took over an application which combines a number of cshtml files written in Razor with a JavaScript spa. I've never seen this structure before and am wondering if anyone has run into this before?
/api
/App_Code
MyCache.cs - caches some data from an external API
Application.cs - looks like the code behind for Global.asax
Api.cshmtl - Uses razor syntax but the entire file is C# and it gets an auth Token and adds it to all api calls.
Global.asax - without global.asax.cs
web.config - not much helpful in here.
index.cshtml
Most of the .cshtml files use Razor syntax. Some are just calling a method from the MyCache.cs via #Html.Raw(myMethodFromCache).
Unfortunately, I don't have a .csproj or .sln file, so it's really hard to guess how this gets compiled. Also no package.config, so I don't know what version of the assemblies, but it only includes:
System.Web.Helpers
System.Web
System.Web.WebPages.Deployment
System.Web.WebPages
System.WebPage.Razor
Have any of you see something like this before? Do you know if this is some older way of handling Spas with .NET?
Any suggestions you have are appreciate.
I finally figured out what this is. It is using ASP.NET Web Pages which is a package available on NuGet. It is a trimmed down version of ASP.NET with the Razor syntax and .cshtml pages without all of the overhead of MVC.
And it was set up to run as a "web site" instead of "web application" which means the application is built at runtime.

Using webpack in combination with Web Forms

I have a webpack configuration that ties together all the dependencies for my web app. The web app is pretty old and is made using Web Forms. I'm going away from using the built in .NET minifier and bundle loader, and instead, towards using webpack's vendor packages etc.
My issue is that the web app is served out of a virtual directory, so I need to be able to reliably locate all required *.js files at runtime for the web app. In my mind I reckon this looks like webpack "somehow" producing an output of what files it has written (including hashes etc), then somehow putting this into my master pages or something. I know there is the HTML plugin for webpack but I don't know how to wrangle that to just produce a list of the *.js files, or if thats even on the right track.
How can I load my webpack'd *.js and *.css files from within Web Forms?
First, you need to install assets-webpack-plugin and configure it in your webpack. You can access this package here in npmjs.org
Why Is This Useful?
When working with Webpack you might want to generate your bundles with a generated hash in them (for cache busting). This plug-in outputs a json file with the paths of the generated assets so you can find them from somewhere else.
There is a good tutorial here to adding styles and scripts dynamically in ASPX.
{
"one": {
"js": "/js/one_2bb80372ebe8047a68d4.bundle.js"
},
"two": {
"js": "/js/two_2bb80372ebe8047a68d4.bundle.js"
}
}
In your aspx or master-page of your web-forms, you can easily deserilize this JSON and load your script and style assets in your page.
I'm using assets-webpack-plugin in my MVC project and I'm sure it wouldn't be a problem to use it in ASPX WebForms.

.net core 2.1 reusing _Layout throughout various projects

I am trying to reuse the same _Layout.cshtml file, throughout multiple .net core 2.1 Razor Page projects. Currently I have a Razor Page Class Library (Common shared project) that is where the _Layout.cshtml file will be located. Along with the layout file there are css and js files that should also be accessible to all other projects (I was able to make this work).
secondary projects will have references to the Common shared project and should be able to utilize the _Layout.cshtml file from it.
My issue is that currently it is not loading the common _layout file when I am accessing pages from these projects, instead it loads its own layout file. If I try deleting this file it throws the error that it cannot find the layout file. However, if I load a page contained inside of the Common shared project it does load its own _layout.
I have used the following tutorials to get where I am at but I could not figure out how to make the secondary projects load the layout in the Common shared project.
Including Static Resources In Razor Class Libraries In ASP.NET Core
Can Razor Class Library pack static files (js, css etc) too
Reuse UI With Razor Class Libraries (RCL) In ASP.NET Core
Please keep in mind that 2 of these articles are based on sharing the css and js files (which did work) but I have read up on other examples for the layout as well and have had no luck (currently I don't have the links to those other articles)
As far as what I have coded I'm currently experimenting on a sample project and its the same as the first article (Including Static Resources In Razor Class Libraries In ASP.NET Core).
UPDATE
Utilizing the 3rd link (Reuse UI With Razor Class Libraries (RCL) In ASP.NET Core) I was able to accomplish my goal. However, I was using this same strategy previously and it was not working. I am going to try playing around with this a bit more. If I have any other updates I will post them.
So apparently since I was working off of the Including Static Resources In Razor Class Libraries In ASP.NET Core link the example left the default razor page class library structure containing the Area/MyFeatures folders. I modified this to work like the last link Reuse UI With Razor Class Libraries (RCL) In ASP.NET Core where the Common shared project is structured the same way that the web application project is (no Area or MyFeatures folder). I also added:
#addTagHelper *,Microsoft.AspNetCore.Mvc.TagHelpers
to the end of my _ViewStart.cshtml located in the Common shared project.
Also just as a note you must delete the _layout.cshtml and _viewstart.cshtml from the web application otherwise it will override the shared project layout.
Anyhow this seems to have fixed the issue and it is now working.

Razor Class Library - Is there a way to compile all Pages/ as Pages/<module name>?

How can you automatically move all RCL pages to a sub-folder of Pages/, such as Pages/<module name> at compile-time, or at WebApplication import-time?
I need this to be transparent such that, in the RCL solution, all pages are in Pages/, but compiled, they are in Pages/<module name>. Or, they're compiled at Pages/, but when imported by the WebApplication, they are hosted in Pages/<module name>.
Is there a project level setting which can prepend the compiled pages with some folder name? Or some other mechanism I can use to achieve the same effect?
Attempted Solutions
I thought about adding routing options to the RCL pages themselves via the #page razor directive but decided against it because it would have to be done to each page individually, and I need something more general which will apply to all pages in a RCL.
I looked up ways to import the RCL content under a different folder via Startup.cs's ConfigureServices() and Configure() but to no success with Conventions. Both PageRouteModel and PageApplicationModel conventions only see the overwritten pages. Also tried to use ConfigureFilter but it ran into the same issue.
Tried to look at adding something in the RCL's root _ViewImports.cshtml to apply some sort of directory offset, but I wasn't able to find good documentation on the razor directives I can use here.

The call is ambiguous between the following methods or properties (bug??)

Create a new ASP.NET MVC Web
Application
Create an ASP.NET App_Code
Folder
Inside the new
folder, create a class with an
Extension Method. For example:
static public class BugMVCExtension
{
public static int ToInt(this string str)
{
return Convert.ToInt32(str);
}
}
Choose a View and try to use this new Extension Method
You will get this Exception:
CS0121: The call is ambiguous between the following methods or properties:
'*MvcApplication1.App_code.BugMVCExtentions.ToInt(string)*' and
'*MvcApplication1.App_code.BugMVCExtentions.ToInt(string)*'
Anyone here has more information about it?
Is it wrong to create an App_code in an ASP.NET MVC(?) Web Applications?
MVC projects created in Visual Studio use Web application project model by default. App_Code is mostly used by Web site model. I suggest reading about differences between them (another question covers this and it's also covered extensively on MSDN). If you add a source file to App_Code in a Web application project, Visual Studio will compile it to a DLL (since it's included in the project) and puts it in /bin. At run time, the ASP.NET compiler sees App_Code and tries to compile the source in a different assembly. As a consequence, two separate classes with identical names will exist in two different assemblies and when the ASP.NET parser tries to compile the .aspx file, it'll fail to choose one.
Update:
Are those two (extension method and the class you're instantiating) in a single .cs file? Otherwise, probably, the class you're instantiating is in a source file with Build Action (right click on file, click properties) set to Content which tells Visual Studio to skip it in the build process (in that case, you won't be able to reference it in other .cs files that are outside App_Code but you'll be able to use it in the view since it'll only come to life at run time.) If the build action is Compile, you'll get an error. The issue is definitely not specific to extension methods. Visual Studio seems to be smart enough to set it to Content by default for source files added to App_Code.
Do not use the app_code folder.
Use any other folder name. IE. appCode or ApplicationsCode.
The name in the folder implies some compilation at runtime that leads to have duplicated code.
I solved the problem by placing the .cs file outside the App_Code folder, in the root of the Web Application.
I solved by placing in the file of extension of the full namespace of the folder.
namespace Helpers
{
namespace xxx.yyy.zzz.Helpers
{

Categories

Resources