ASP.NET bundling and minification not producing query string params - asp.net

I've been using ASP.NET bundling and minification with the nugget package Microsoft.AspNet.Web.Optimization.
I noticed yesterday that the majority of my bundle files no longer have the v query string parameter to the exception of one of them:
/Sgc.Web/bundles/css/JQueryUI
/Sgc.Web/bundles/css/DefaultPage
/Sgc.Web/bundles/js/Menu
/Sgc.Web/bundles/js/DefaultPage
/Sgc.Web/bundles/js/ReportOutputs
/Sgc.Web/bundles/js/UnderscoreBackbone?v=4YsZ6DBVserabs64GE87Ua4d51aeg0D1wXHWNe3E6NU1
The JS bundle that still has the query string always keeps on producing different v param values after I do changes on it (as expected). However the remaining bundles (either css or js) when I make changes on their css or js files they do incorporate those changes but do not produce a v param value any more.
The C# code to perform the bundling:
// -- create and add CSS bundles without minification
BundleTable.EnableOptimizations = true;
bundles.Add(new Bundle("~/bundles/css/JQueryUI").Include(
"~/Styles/Gui/jquery-ui-1.10.4-custom.css",
"~/Styles/Gui/jquery-ui-custom.css",
"~/Styles/Gui/jquery.ui.combogrid.css"));
bundles.Add(new Bundle("~/bundles/css/DefaultPage").Include(
"~/Styles/Default.css",
"~/Content/toastr.min.css"));
// -- create and add JS bundles without minification
bundles.Add(new Bundle("~/bundles/js/DefaultPage").Include(
"~/Scripts/Defaults.js",
"~/Scripts/toastr.min.js"));
bundles.Add(new Bundle("~/bundles/js/Menu").Include(
"~/Scripts/Gui/Menus/SuperFish/jquery.hoverIntent.r7.min.js",
"~/Scripts/Gui/Menus/SuperFish/superfish1_7_4.min.js",
"~/Scripts/Gui/Menus/SuperFish/factory.js"));
bundles.Add(new Bundle("~/bundles/js/UnderscoreBackbone").Include(
"~/Scripts/underscore.min.js",
"~/Scripts/backbone.min.js"));
bundles.Add(new Bundle("~/bundles/js/ReportOutputs").Include(
"~/Scripts/Gui/jquery-visibility.js",
"~/Scripts/UserControls/ReportOutputs.js"));
//-- if in Release mode, then minify all the bundles
if (!System.Web.HttpContext.Current.IsDebuggingEnabled)
{
CssMinify cssMinify = new CssMinify();
JsMinify jsMinify = new JsMinify();
foreach (Bundle bundle in bundles)
{
if (bundle.Path.Contains("/js"))
{
bundle.Transforms.Add(jsMinify);
}
else
{
bundle.Transforms.Add(cssMinify);
}
}
As can be seen from above I'm building the bundle with the Bundle super class instead of the StyleBundle or ScriptBundle sub classes. However I also tried to make bundles with these 2 subclasses and the result was the same: all bundles still didn't had v param to the exception of the UnderscoreBackbone bundle. As far as I know there is no difference in the way the UnderscoreBackbone bundle is being made and the remaining bundles.
I'm using,
Windows 8.1
VS Premium 2013 with Update 1
Microsoft.AspNet.Web.Optimization 1.1.3
WebGrease 1.6.0
Microsoft.Web.Infrastructure 1.0.0.0
Json.NET (Newtonsoft.Json) 6.0.1
ANTLRv3 3.5.0.2
Does anyone ever faced this kind of problem before or any hint as to where can I look for a solution to it ?
Thanks in advance,
MggLp

Sometimes, in views, we might be doing something like -
Scripts.Render("/bundles/js/Default‌​Page")
but the correct syntax to get hash -
Scripts.Render("~/bundles/js/Default‌​Page").
It might be the matter of absolute and relative path.
Using ~ we can get the querystring for the bundled files.

Related

What does AspNet.ScriptManager.bootstrap do?

I was trying to update bootstrap from 4.6.0 to 5.1.3, and when I do so I get the error message 'bootstrap 5.1.3' is not compatible with 'AspNet.ScriptManager.bootstrap 4.6.0 constraint: bootstrap (>= 4.5.9 && <= 4.6.1)'.
The latest version of AspNet.ScriptManager.bootstrap is 4.6.0 (released 2021-03-16).
What does AspNet.ScriptManager.bootstrap do and how can I replace it?
First a bit of background. The type PreApplicationStartCode is used to hookup bundles. The type is used by convention, it is static and has a static method Start (no parameters). It gets called by System.Web.Optimization.
So, AspNet.ScriptManager.bootstrap consists of a dll which contains a namespace which contains a type of PreApplicationStartCode which has a Start method which adds a ScriptResourceDefinition to the ScriptManager.ScriptResourceMapping.
It can be replaced by adding a call in your Application_Start handler (or a method it calls, typically BundlesConfig.RegisterBundles) to
ScriptManager.ScriptResourceMapping.AddDefinition("bootstrap",
new ScriptResourceDefinition {
Path = "~/Scripts/bootstrap.min.js",
DebugPath = "~/Scripts/bootstrap.js",
CdnPath = "https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.bundle.min.js",
CdnSupportsSecureConnection = true,
LoadSuccessExpression="window.jQuery.fn.carousel"
});
And voila, the package AspNet.ScriptManager.bootstrap can be removed and there will be no problem updating bootstrap.

BundleTransformer for less complaining "Could not find a factory, that creates an instance of the JavaScript engine"

If you upgrade from version 1 to version 2 of BundleTransformer you may get this message:
Could not find a factory, that creates an instance of the JavaScript
engine with name MsieJsEngine.
Like me, you may not even have realized you've upgraded more than just a point release.
How to fix?
Version 2 DOES NOT USE WEB.CONFIG for configuration anymore
So start by removing it and read the rest of this link
https://github.com/Taritsyn/JavaScriptEngineSwitcher/wiki/How-to-upgrade-applications-to-version-2.X
Basically you will be doing the following:
Removing existing web.config nodes for javscript engine
Adding to someplace like global.asax some initialization code
Install Nuget packages for the engines you want to use
Make sure to add a using statement to be able to use extension methods (if you choose that way)
I ended up with something like this:
using JavaScriptEngineSwitcher.Core;
using JavaScriptEngineSwitcher.Msie;
using JavaScriptEngineSwitcher.V8;
....
public class JsEngineSwitcherConfig
{
public static void Configure(JsEngineSwitcher engineSwitcher)
{
engineSwitcher.EngineFactories
.AddMsie(new MsieSettings
{
UseEcmaScript5Polyfill = true,
UseJson2Library = true
})
.AddV8();
engineSwitcher.DefaultEngineName = MsieJsEngine.EngineName;
}
}
I'm following the instructions, but my code is now breaking on BundleConfig
var cssTransformer = new StyleTransformer();
In the name attribute of /configuration/bundleTransformer/less/jsEngine configuration element not specified a name of JavaScript engine.
If you have not installed JavaScript engine, then for correct working
of this module is recommended to install one of the following NuGet
packages: * JavaScriptEngineSwitcher.Msie *
JavaScriptEngineSwitcher.V8 * JavaScriptEngineSwitcher.ChakraCore
After package is installed, need set a name of JavaScript engine (for
example, MsieJsEngine) to the name attribute of
/configuration/bundleTransformer/less/jsEngine configuration
element.

spring boot/spring web app embedded version number

What are the strategies to embed a unique version number in a Spring application?
I've got an app using Spring Boot and Spring Web.
Its matured enough that I want to version it and see it displayed on screen at run time.
I believe what you are looking for is generating this version number during build time (Usually by build tools like Ant, Maven or Gradle) as part of their build task chain.
I believe a quite common approach is to either put the version number into the Manifest.mf of the produced JAR and then read it, or create a file that is part of the produced JAR that can be read by your application.
Another solution would be just using Spring Boot's banner customization options described here: http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-spring-application.html#boot-features-banner
However, this will only allow you to change spring-boot banner.
I also believe that Spring Boot exposes product version that is set in Manifest.MF of your application. To achieve this you will need to make sure Implementation-Version attribute of the manifest is set.
Custom solution for access anywhere in the code
Lets assume you would like to have a version.properties file in your src/main/resources that contains your version information. It will contain placeholders instead of actual values so that these placeholders can be expanded during build time.
version=${prodVersion}
build=${prodBuild}
timestamp=${buildTimestamp}
Now that you have a file like this you need to fill it with actual data. I use Gradle so there I would make sure that processResources task which is automatically running for builds is expanding resources. Something like this should do the trick in the build.gradle file for Git-based code:
import org.codehaus.groovy.runtime.*
import org.eclipse.jgit.api.*
def getGitBranchCommit() {
try {
def git = Git.open(project.file(project.getRootProject().getProjectDir()));
def repo = git.getRepository();
def id = repo.resolve(repo.getFullBranch());
return id.abbreviate(7).name()
} catch (IOException ex) {
return "UNKNOWN"
}
}
processResources {
filesMatching("**/version.properties") {
expand (
"prodVersion": version,
"prodBuild": getGitBranchCommit(),
"buildTimestamp": DateGroovyMethods.format(new Date(), 'yyyy-MM-dd HH:mm')
)
}
}
processResources.outputs.upToDateWhen{ false }
In the code about the following is happening:
We defined a function that can take a build number out of the VCS
(in this case Git). The commit hash is limited to 7 characters.
We configure the processResources task to process
version.properties file and fill it with our variables.
prodVersion is taken from Gradle project version. It's usually set
as version in gradle.properties file (part of the general build
setup).
As a last step we ensure that it's always updated (Gradle
has some mechanics to detect if files ened to be processed
Considering you are on SVN, you will need to have a getSvnBranchCommit() method instead. You could for instance use SVNKit or similar for this.
The last thing that is missing now is reading of the file for use in your application.
This could be achieved by simply reading a classpath resource and parsing it into java.util.Properties. You could take it one step further and for instance create accessor methods specifically for each field, e.g getVersion(), getBuild(), etc.
Hope this helps a bit (even though may not be 100% applicable straight off)
Maven can be used to track the version number, e.g.:
<!-- pom.xml -->
<version>2.0.3</version>
Spring Boot can refer to the version, and expose it via REST using Actuator:
# application.properties
endpoints.info.enabled=true
info.app.version=#project.version#
Then use Ajax to render the version in the browser, for example using Polymer iron-ajax:
<!-- about-page.html -->
<iron-ajax auto url="/info" last-response="{{info}}"></iron-ajax>
Application version is: [[info.app.version]]
This will then show in the browser as:
Application version is: 2.0.3
I'm sure you've probably figured something out since this is an older question, but here's what I just did and it looks good. (Getting it into the banner requires you to duplicate a lot).
I'd recommend switching to git (it's a great SVN client too), and then using this in your build.gradle:
// https://github.com/n0mer/gradle-git-properties
plugins {
id "com.gorylenko.gradle-git-properties" version "1.4.17"
}
// http://docs.spring.io/spring-boot/docs/current/reference/html/deployment-install.html
springBoot {
buildInfo() // create META-INF/build-info.properties
}
bootRun.dependsOn = [assemble]
And this in your SpringBoot application:
#Resource
GitProperties props;
#Resource
BuildProperties props2;
Or this way to expose those properties into the standard spring environment:
#SpringBootApplication
#PropertySources({
#PropertySource("classpath:git.properties"),
#PropertySource("classpath:META-INF/build-info.properties")
})
public class MySpringBootApplication {
and then referencing the individual properties as needed.
#Value("${git.branch}")
String gitBranch;
#Value("${build.time}")
String buildTime;

is Scripts/Home a reserved name for bundle?

If i do
//BundleConfig.cs
bundles.Add(new ScriptBundle("~/Scripts/Home").Include("~/Scripts/Home/Home.js"));
//index.cstml
#section scripts
{
#Scripts.Render("~/Scripts/Home")
}
then the script is not going to get rendered in release mode, it works fine in debug mode without
BundleTable.EnableOptimizations = true;
but if i do
//BundleConfig.cs
bundles.Add(new ScriptBundle("~/bundles/Home").Include("~/Scripts/Home/Home.js"));
//index.cstml
#section scripts
{
#Scripts.Render("~/bundles/Home")
}
then it works fine in both debug and release mode.
Is Scripts/Home a reserved name or something?
Note: I do not have anything else named ~/Scripts/Home in BundleConfig.cs
Not Scripts/Home in particular but it must be a valid bundle name, or path to an actual file.
For example if you were to add the following to your View without adding the appropriate bundle name it would actually render the script directly from disk to the browser. (yay)
#Scripts.Render("~/scripts/jquery-1.8.2.js")
But any reference to a non existent file or bundle name would cause an error, like these:
#Scripts.Render("~/scripts/jquery/*.*") -- error, no wildcards either
#Scripts.Render("~/non-existant-directory-or-bundle-name") -- error
#Scripts.Render("~/scripts/no-such-file.js") -- error
No, however the bundle name (~/Scripts/Home) cannot match either an existing folder or file.
For this reason, I leave my scripts in ~/Scripts/... but name the bundles ~/js/....

Can't set up asp.net mvc 2 RC and spark view engine

Does omebody has ideas how to fix "Method not found: 'Void System.Web.Mvc.ViewContext..ctor(System.Web.Mvc.ControllerContext, System.Web.Mvc.IView, System.Web.Mvc.ViewDataDictionary, System.Web.Mvc.TempDataDictionary)'." exception. This solution doesn't work http://dotnetslackers.com/articles/aspnet/installing-the-spark-view-engine-into-asp-net-mvc-2-preview-2.aspx.
Thans for all.
I had to download the spark view engine source code (http://sparkviewengine.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=27600). Once I did that I went through each of the projects that had a reference to the 1.0 version of System.Web.Mvc assembly and updated to reference to point to System.Web.Mvc 2.0. From there you can build the solution (in visual studio) and you will find that a whole bunch of tests start to fail. You can attempt to fix them (by adding the additional TextWriter parameter you will find is now needed). You will also see that the SparkView.cs file complains about a missing parameter. In the Render method (line 100 of the source code I downloaded) I had to update the instantiation of the wrappedViewContext to look like this (add writer to the end of the list of parameters):
public void Render(ViewContext viewContext, TextWriter writer)
{
var wrappedHttpContext = new HttpContextWrapper(viewContext.HttpContext, this);
var wrappedViewContext = new ViewContext(
new ControllerContext(wrappedHttpContext, viewContext.RouteData, viewContext.Controller),
viewContext.View,
viewContext.ViewData,
viewContext.TempData,
writer); // <-- add the writer to the end of the list of parameters
...
}
Once the code is updated you can run the build.cmd script that is in the root of the source you downloaded. The build process will create a zip file in the build/dist folder. Take those new dll's and add them to your website. Things should work once again.
At the time of this answer, MVC 2 RC2 bits are available at sparkviewengine.codeplex.com
http://sparkviewengine.codeplex.com/releases/view/41143
It was actually Erik from the post mentioned by R0MANARMY who helped get those bits out there.
Looks like you can also download compiled binaries from here. As the post says, it isn't a final (or official) release, but at least it seems like the unit tests pass.

Resources