Include static files in a reusable Razor Class Library - javascript

I am trying to make a reusable class library (RCL) that I can use in several ASP.NET Core MVC projects. So far so good… until I try to include the required JavaScript in the RCL. There is little-to-no documentation about this topic. My best shot was to try this example.
But when I do, I get the following error when I build the library:
This is the project file and the structure of the library:
Any help is appreciated.

Now that I have some spare time I will answer my own question. Maybe it will useful for someone.
Finally I solved this problem using EmmbededResources without the EmbeddedFilesManifest as ianbusko pointed out in Github.
First I created an extension for the IApplicationBuilder class:
namespace Dashboard.Lib.Extensions
{
public static class IApplicationBuilderExtension
{
public static void UseDashboardScripts(this IApplicationBuilder builder)
{
var embeddedProvider = new EmbeddedFileProvider(typeof(Areas.Dashboard.ViewComponents.DashboardViewComponent)
.GetTypeInfo().Assembly, "Dashboard.Lib.Scripts");
builder.UseStaticFiles(new StaticFileOptions()
{
FileProvider = embeddedProvider,
RequestPath = new PathString("/Scripts")
});
}
}
}
Then I added the javascript files to the project file:
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<GenerateEmbeddedFilesManifest>false</GenerateEmbeddedFilesManifest>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.1.3" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="2.1.1" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Scripts/**/**/**/*" Pack="true" />
</ItemGroup>
In the RCL view the javascript is included as follows:
#section Scripts{
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script type="text/javascript" src="~/Scripts/pagination.js"></script>
<script type="text/javascript" src="~/Scripts/checkdigit-validator.js"></script>
<script type="text/javascript" src="~/Scripts/rut-validation.js"></script>
}
Finally in the Statup.cs in the main MVC project you just have to include the following:
app.UseStaticFiles();
app.UseDashboardScripts();

Related

Blazor WebAssembly load different scripts for specific Environment

I'm currently working on a .NET Standard 2.1 Blazor WebAssembly application. I try to include or exclude JavaScript files in my index.html according to an environment variable.
The Blazor WebAssembly App is NOT Asp.NET Core hosted.
In .NET Core there are usually Environment Tag Helpers like in the following example:
<environment include="Development">
<script src="js/app.js"></script>
<script src="js/helpers.js"></script>
</environment>
<environment exclude="Development">
<script src="js/site.min.js"></script>
</environment>
As already discussed in this question Blazor WebAssembly Environment Variables, the Environment Tag Helpers are server side code and thus don't work in Blazor WASm.
Now I try to find a good solution to include/exclude JavaScript files according to the Environment variable in Blazor WebAssembly.
The first idea was, similar like for CSS, to create a component called <Scripts> to load the different script files on the index.html like this:
#using Microsoft.AspNetCore.Components.WebAssembly.Hosting
#inject IWebAssemblyHostEnvironment hostEnv
#*Check the environment value*#
#if (hostEnv.IsDevelopment())
{
<script src="js/app.js"></script>
<script src="js/helpers.js"></script>
}
else
{
<script src="js/site.min.js"></script>
}
#code {}
Unfortunately this doesn't work, because the <script> Element is not allowed to be used in a Blazor component (.razor file).
The following error occurs: The script element allows authors to include dynamic script and data blocks in their documents. The element does not represent content for the user. ... Script tags should not be placed inside components because they cannot be updated dynamically. To fix this, move the script tag to the 'index.html' file or another static location. ... https://go.microsoft.com/fwlink/?linkid=872131
How do you load different scripts according to the Environment Variable i.e. Development, Production or Staging in Blazor Webassembly?
Do you know how to solve this problem?
I wanted to add Tailwind CDN script tag just during development. I ended up using the solution below:
index.html
<script src="_framework/blazor.webassembly.js"></script>
<script>
// If localhost, add tailwind CDN (or any other script that you want)
if (window.location.hostname == 'localhost') {
var customScript = document.createElement('script');
customScript.setAttribute('src', 'https://cdn.tailwindcss.com');
document.head.appendChild(customScript);
}
</script>
Simply copy your index.html code in a .cshtml (named BlazorApp.cshtml in the following sample) in your server project and fallback to this page.
public void Configure(IApplicationBuilder app)
{
...
app.UseEndpoints(endpoints =>
{
...
endpoints.MapFallbackToPage("/BlazorApp");
}
}
And update the code with <environment> tags for your conveniance.
Please check the solution in this answer (same question as you linked above) and that seems to work.
Basically the workaround is to use this in a new component called Head.razor as per the solution:
#inject IWebAssemblyHostEnvironment hostEnv
#if (hostEnv.IsDevelopment())
{
<title>BlazorWasmApp - In Debug</title>
<link href="css/debug.css" rel="stylesheet" />
}
else
{
<title>BlazorWasmApp - Not Debug</title>
<link href="css/live.css" rel="stylesheet" />
}
New Head.razor component:
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
//Add the Head to root components
builder.RootComponents.Add<Head>("head");
builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
await builder.Build().RunAsync();
}

how to load js and css file from web content spring mvc

I am unable to load JS and CSS file from webcontent folder.My login page goes without formatting please suggest me how to load this I am not using maven.
Plz find the image.
1) Create "resources" folder.
2) Add this in your xml file:
<mvc:resources mapping="/resources/**" location="/resources/" />
3)"Use" it in your page:
<link href="<c:url value="/resources/name_of_file.css" />" rel="stylesheet">
If you use Java Config, something like this will do the job:
#Configuration
#EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/resources/**")
.addResourceLocations("/resources/");
}
}

Bundling and Minification Confusion

I'm using ASP.NET Web Forms with master pages. There are so many moving parts to this that I cannot figure it out. Different tutorials use different parts of it and omit others, that I cannot determine what is needed and what is fluff.
Different Parts:
Master Pages: In the head section for my CSS I have:
<link href="Content/css" rel="stylesheet" />
<asp:PlaceHolder runat="server">
<%: Scripts.Render("~/bundles/modernizr") %>
</asp:PlaceHolder>
Before closing body tag, I have:
<script src="<%= ResolveUrl("~") %>Scripts/jquery-2.1.1.js"></script>
<script src="<%= ResolveUrl("~") %>Scripts/bootstrap.min.js"></script>
<script src="<%= ResolveUrl("~") %>Scripts/jquery.reject.js"></script>
<script src="<%= ResolveUrl("~") %>Scripts/general.js"></script>
Looks like the min one is not needed, but do I need any of these and instead use
<script src="Scripts/js"></script> ?
Global.asax.cs: this seems simple enough, registering the bundles in Application_Start method.
void Application_Start(object sender, EventArgs e)
{
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
Web.config:
I added the System.Web.Optimization namespace and the Microsoft.AspNet.Web.Optimization.WebForms assembly.
Bundle.config: I have no idea what this is for; many tutorials don't even mention it?
BundleConfig.cs: As well as the standard WebFormsJs, MsAjaxJs and modernizr custom bundles, I have the following for CSS:
bundles.Add(new StyleBundle("~/bundles/css").Include(
"~/Content*"));
This is not working. I was about to add something similar for my JS files but got confused as to why I am doing this at all when according to this tutorial, all I needed for the CSS was:
<link href="Content/css" rel="stylesheet" />
Presumably, all I needed for my JS files was:
<script src="Scripts/js"></script>
In some tutorials I have seen ScriptManager.ScriptResourceMapping.AddDefinition - what is this for?
Here is the current state of my CSS and Scripts folders - I need all the non-minifed versions of these:
http://imgur.com/XwqIOKl
http://imgur.com/q8IdhmB
Can someone help me piece this together? I am running locally with debug set to false.
Below is a list of each of the sections that need to be configured for Bundling and Minification in WebForms.
This is taken from a production code base which is running Bundling and Minification.
Libraries:
Microsoft.AspNet.Web.Optimization
Dependencies:
WebGrease
Microsoft.Web.Infrastructure (depending on version)
Global.asax
void Application_Start(object sender, EventArgs e)
{
BundleConfig.RegisterBundles(BundleTable.Bundles);
//Use this if you want to force/test bundling in debug.
BundleTable.EnableOptimizations = true;
}
BundleConfig class
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/sitejs")
//Add as many JS libraries you would like to the bundle...
.Include("~/Scripts/jquery-3.1.1.js")
.Include("~/Scripts/jquery-migrate-3.0.0.js")
);
bundles.Add(new StyleBundle("~/bundles/sitecss")
//Add as many CSS files that you would like to the bundle...
.Include("~/css/jquery-ui.css")
);
}
}
Master Page:
<!-- At the top of the Master Page -->
<%# Import Namespace="System.Web.Optimization" %>
<!-- Just after the closing `</form>` tag -->
<asp:PlaceHolder runat="server">
<%: Styles.Render("~/bundles/sitecss") %
<%: Scripts.Render("~/bundles/sitejs") %
</asp:PlaceHolder>

How to include js files in the view. ASP.NET MVC 4

I wonder why my js file work when I call it in the view:
#section Scripts {
<script>
function myFunction() {
alert("Hello1");
}
</script>
}
but does not work when I call it:
#section Scripts {
<script type="text/javascript" src="~/Views/Home/script.js"></script>
<script>
myFunction();
</script>
}
It's because .js files are not accessible in the ~/Views/ folder. You have to enable it.
To enable access to .js files in the Views folder, you can add the following to your Views' folder's web.config directly under the handlers tag:
<add name="JavaScriptHandler"
path="*.js"
verb="*"
preCondition="integratedMode"
type="System.Web.StaticFileHandler" />
Alternatively put your script into the ~/Scripts/ folder and reference it like such:
#Scripts.Render("~/Scripts/script.js")
Its better practice to place your Js file in Script folder and access it from there. You could write this code in view's head to use the js file
#Scripts.Render("~/Scripts/script.js")
you have to add your script in the Bundle config :
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js", "~/Views/Home/script.js"));
this worked for me
You should Add rendersection to your Layout Page which your view using.
#RenderSection("scripts", required: false)

Using JavaScript in Ant

I am having issues using the <script> tag in Ant and I am hoping someone can help. I want to use JavaScript in my Ant build.xml. Something like the following:
<?xml version="1.0" encoding="UTF-8"?>
<project name="java" default="main" basedir=".">
<target name="main">
<script language="javascript"> <![CDATA[
println("hello, world")
]]> </script>
</target>
</project>*
Unfortunately this only displays and error:
build.xml:4: Could not create task or type of type: script.
I have located the required jar file (js.jar) for this to work and moved it to ANT_HOME/lib, but I am still stuck as of how to get this to work.
In addition to js.jar, you need to add bsf.jar and commons-logging-*.jar to ANT_HOME/lib. In your Ant distribution, there is a file named docs/manual/install.html. The Library Dependencies section of this HTML file documents where you can download these files.
println isn't supported in JavaScript. Instead, use the following:
<project name="jsTest" default="main">
<target name="main">
<script language="javascript"> <![CDATA[
var echo = jsTest.createTask("echo");
echo.setMessage("hello, world");
echo.perform();
]]> </script>
</target>
</project>
You can also instantiate and use Java classes in Javascript as available via Rhino(JRE pre 1.8) or Nashorn(JRE 1.8+) when you need to.
<script language="javascript">
with(new JavaImporter(java.lang, java.io)){
System.out.println("hello, world");// <--!!!
}
</script>
You may create and use JavaScript functions of your own.
<script language="javascript">
with(new JavaImporter(java.lang, java.io)){
var fun = function(a,b){
System.out.println(a+b);
};
fun(1,2);
}
</script>
Code above prints
3.0
Loops, recursion and everything you've been dreaming about... except strong type checking:-)
Beside the two syntax errors - missing ';' after println.. and trailing '*' after closing project tag - you should upgrade your ant installation to a version >= 1.7.x in conjunction with jdk >= 6 to be able to use the builtin javascript engine.
When using jdk >=6 the use of println is no problem, see :
import javax.script.*;
public class ExecuteJS {
public static void main(String[] args) throws Exception {
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
engine.eval("print('Line1')");
engine.eval("println('Line2')");
engine.eval("print('Line3')");
engine.eval("println('Line4')");
}
}
output :
Line1Line2
Line3Line4
and
<project>
<script language="javascript">
println("hello, world");
</script>
</project>
But further testing with Ant 1.9.0 / Win7 (my linux box is down right now) / jdk1.7.0_21 revealed some oddities :
<project>
<script language="javascript">
println("hello, world");
</script>
</project>
works
<project default="foo">
<target name="foo">
<script language="javascript">
println("hello, world");
</script>
</target>
</project>
works also
<project name="whatever" default="foo">
<target name="foo">
<script language="javascript">
println("hello, world");
</script>
</target>
</project>
works also, whereas
<project name="java" default="foo">
<target name="foo">
<script language="javascript">
println("hello, world");
</script>
</target>
</project>
results in
BUILD FAILED
javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: TypeError: Cannot read property "PrintWriter" from undefined (print#8) in print at line number 8
Strange !? Seems like a bug, so finally upgrade ant >= 1.7.x and jdk >= 1.6 and don't use 'java' in name attribute of project :-)

Categories

Resources