For readability I created my stylesheets like this:
div.icons,div.sizes,div.configs
{
width:213px;
float:left;
}
Is it necessary to use this style for performance reasons:
div.icons,div.sizes,div.configs{width:213px;float:left;}
I am using ASP.NET webforms. Can I still use the bundling functionality from ASP.NET MVC for this?
No, you don't need to style it like that for performance reasons. Write it for readability. Bundling and minification will handle the performance part.
Yes, bundling and minification works in Webforms. Here are key steps from the post Adding Bundling and Minification to Web Forms:
Create your bundle:
using System.Web.Optimization;
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));
//...
Register your bundle: (global.asax)
void Application_Start(object sender, EventArgs e)
{
BundleConfig.RegisterBundles(BundleTable.Bundles);
//...
Reference your bundle: (masterpage)
<asp:PlaceHolder runat="server">
<%: Scripts.Render("~/bundles/jquery") %>
</asp:PlaceHolder>
Get bundling and minification from NuGet.
I would not write css or JavaScript with that in mind. Instead I would rely on a minifier to do the job. That way your css files are readable.
Related
I'm trying to add Script and Style Bundling to a fairly old legacy WebForms application. It works great in debug mode or with BundleTable.EnableOptimizations = false.
But when I try to enable optimizations as it should be in production, it's not actually creating the bundles so they are returning 302 Not Found errors.
Here's my BundleConfig class
public static void RegisterBundles(BundleCollection bundles)
{
bundles.IgnoreList.Clear();
bundles.Add(new ScriptBundle("~/bundles/js")
.Include("~/Scripts/jquery-{version}.js",
"~/Scripts/jquery-migrate-{version}.js",
"~/Scripts/jquery-validate.js",
"~/Scripts/jquery-validate-unobtrusive.js",
"~/Scripts/bootstrap.min.js",
"~/Scripts/css_browser_selector.js",
"~/Scripts/menu.js",
"~/Scripts/owl.carousel.js",
"~/Scripts/owl.carousel2.thumbs.js",
"~/Scripts/general.js"));
bundles.Add(new StyleBundle("~/bundles/css")
.Include("~/css/bootstrap.css",
"~/css/owl.carousel.min.css",
"~/css/menu.css",
"~/css/style.css",
"~/css/responsive.css",
"~/css/faeaapps_style.css"
));
BundleTable.EnableOptimizations = true;
}
Application_Start in Global.asax:
BundleConfig.RegisterBundles(BundleTable.Bundles);
In the of the master page:
<asp:PlaceHolder runat="server">
<%: Scripts.Render("~/bundles/js") %>
<%: Styles.Render("~/bundles/css") %>
</asp:PlaceHolder>
How they're getting rendered:
<script src="/AppName/bundles/js?v=wMldU3OL4sMBTxZpOsGwPTsnbckw_2T1BVZNp1Lopag1"></script>
<link href="/AppName/bundles/css?v=Mdb6m_Rz-GAE4EuPddeqG8CHLfgK1ODoN0WhXZmy09k1" rel="stylesheet"/>
What happens when the browser tries to load them:
Any idea what I'm doing wrong?
This has been asked before, but nobody responded, so I ask again as I feel it is important.
Unobtrusive validation for web forms works great, but, only when validation controls are added to a form. For other pages that lack validation controls, no reference to the JQuery file is rendered.
I currently use JQuery on all pages, so reference it manually in a Master page file,
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
The problem is that when I access a page with my own JQuery logic and validation controls, then two references get created (my own, plus ASP.Net's ScriptResourceDefinition).
How can I achieve one of the following:
Let ScriptResourceDefinition know that the file exists and has already been added?
Force ScriptResourceDefinition to render JQuery on every page regardless of whether it detects validation controls?
Found the answer here https://stackoverflow.com/a/12628170/792888
The answer is to inherit from ScriptManager and stop ASP.Net's built-in behaviour of creating the unnecessary (duplicate) JQuery link
using System;
using System.Linq;
using System.Web.UI;
namespace WebApplication46
{
public class CustomScriptManager : ScriptManager
{
protected override void OnInit(EventArgs e)
{
Page.PreRenderComplete += Page_PreRenderComplete;
base.OnInit(e);
}
private void Page_PreRenderComplete(object sender, EventArgs e)
{
var jqueryReferences = Scripts.Where(s => s.Name.Equals("jquery", StringComparison.OrdinalIgnoreCase)).ToList();
if (jqueryReferences.Count > 0)
{
// Remove the jquery references as we're rendering it manually in the master page <head>
foreach (var reference in jqueryReferences)
{
Scripts.Remove(reference);
}
}
}
}
}
In web.config this is wired up to replace the standard ScriptManager:
<system.web>
<pages>
<tagMapping>
<add tagType="System.Web.UI.ScriptManager" mappedTagType="WebApplication46.CustomScriptManager" />
</tagMapping>
</pages>
</system.web>
I want to add Bundles into an existing ASP.NET MVC 4 (.NET 4.5) website that uses:
Umbraco 6.1.5
Microsoft ASP.NET Web Optimization Framework 1.1.3 (https://www.nuget.org/packages/microsoft.aspnet.web.optimization/)
I attempted to follow these directions: https://gist.github.com/jkarsrud/5143239, and the CSS loaded fine before I started down the bundles path.
On page load it inserts the style reference:
<link href="/bundles/marketingcss" rel="stylesheet">
But a 404 error happens:
> GET http://localhost:20459/bundles/marketingcss 404 (Not Found)
Here's what I've in code:
Web.Config
<add key="umbracoReservedPaths" value="~/umbraco,~/install/,~/bundles" />
Global.asax
<%# Application Codebehind="Global.asax.cs" Inherits="MapCom.Global" Language="C#" %>
Global.asax.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Optimization;
using System.Web.Security;
using System.Web.SessionState;
using Umbraco.Web;
namespace MapCom
{
public class Global : UmbracoApplication
{
protected void Application_Start(object sender, EventArgs e)
{
base.OnApplicationStarted(sender, e);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
}
_Layout.cshtml
#Styles.Render("~/bundles/marketingcss");
BundleConfig.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Optimization;
namespace MapCom
{
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
BundleTable.EnableOptimizations = true;
///
///Marketing Site CSS Bundle
///
bundles.Add(new StyleBundle("~/bundles/marketingcss")
.Include("~/plugins/bootstrap/css/bootstrap.min.css")
.Include("~/css/font-awesome.min.css")
.Include("~/plugins/parallax-slider/css/parallax-slider.css")
.Include("~/css/combinedStyles.min.css")
.Include("~/plugins/ladda-buttons/css/ladda.min.css")
.Include("~/plugins/ladda-buttons/css/custom-lada-btn.css"));
}
}
}
Any ideas?
After much digging into Umbraco, I noticed that the project I'm working on is utilizing a class:
public class ApplicationEventHandler : IApplicationEventHandler
Which is explained in more detail here: http://our.umbraco.org/documentation/Reference/Events/application-startup
But the gist is:
In order to bind to certain events in the Umbraco application you need to make these registrations during application startup. Based on the Umbraco version you are using there are various ways to hook in to the application starting. The higher the version you are using the more robust this becomes.
So Umbraco's overriding some of the ASP.NET start-up methods.
I solved my issue by adding a reference to System.Web.Optimization in ApplicationEventHandler.cs and moved my bundle registration to this method in that class:
public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
The ONLY thing that worked for me here was adding the path to the bundle to the following setting in web.config
My bundle Code
BundleTable.Bundles.Add(new ScriptBundle("~/opt/jscripts").Include(
"~/Scripts/twitterFetcher.js"
));
BundleTable.EnableOptimizations = true;
Umbraco default setting
<add key="umbracoReservedPaths" value="~/umbraco,~/install/" />
New setting
<add key="umbracoReservedPaths" value="~/umbraco,~/install/,~/opt/" />
try the following suggestions:
1.Do not use keyword bundles for your css virtual path so just change it to something else, and use the keyword bundles for your scripts only.
like this:
bundles.Add(new StyleBundle("~/Content/marketingcss")
(Remember you need to make sure that if you have a file called marketingcss under content folder you should change the virtual path to something else, so the virtual path shouldn't duplicate the physical path)
2.in your _Layout.cshtml use the following line instead of yours:
#Styles.Render(BundleTable.Bundles.ResolveBundleUrl("~/Content/marketingcss"))
3.if the above suggestions didn't work then try this one in your _Layout.cshtml instead:
<link href="#System.Web.Optimization.BundleTable.
Bundles.ResolveBundleUrl("~/Content/marketingcss")"
rel="stylesheet"
type="text/css" />
updated
4.just saw one of our friend's comment about not to putting .min files in your bundle, which is correct so you must not include .min files in your budleConfig class, and just use the normal files like bootstarp.css instead of bootstrap.min.css and do the same for all other files, of course make sure you have the normal files first so not just change the names.
I hope it helps to fix your code
I have a .aspx file and would like to add some HTML to it. The problem is that it can't be modified. If I upgrade the product, this .aspx file will be overwritten and my modifications would have to be done again.
This is an open source product, so I can have a look at the codebehind. Again, I cannot modify it because that would break my upgrade path. Also, I need to add functionality that would never be included in the product, so sending in a patch is useless.
The class that's referred to is a partial class, so I tried implementing an extra Page_PreRender by creating another partial class of the same name in the same namespace. However, since this is in another assembly, .net says it doesn't know which is the correct class.
Is there any way I can do this?
So you can neither touch the .aspx of this page, nor the assembly containing its code behind? Sounds like you need to create a PageAdapter.
Say you're given this page...
<%# Page AutoEventWireup="true" ContentType="text/plain" Inherits="WebForm1" %>
SomeControl: <asp:Literal runat="server" ID="SomeControl" />
...with this code behind (in an assembly that you can only reference, not modify).
public class WebForm1 : Page {
protected void Page_Load(object sender, EventArgs e) {
var SomeControl = (Literal) FindControl("SomeControl");
SomeControl.Text = "Value set from code-behind.";
}
}
What you can do is create a PageAdapter like so (in your own assembly):
public class WebForm1Adapter : PageAdapter {
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
var SomeControl = (Literal) Page.FindControl("SomeControl");
SomeControl.Text = "Value set from control adapter.";
}
}
Then finally, you need to register your override by creating a browser definition file:
<browsers>
<browser refID="Default">
<controlAdapters>
<adapter controlType="WebForm1" adapterType="WebForm1Adapter" />
</controlAdapters>
</browser>
</browsers>
Check the PageAdapter and ControlAdapter documentation to find out all the ways you can override the normal page behavior.
This should make updating the third party page much less painful. No matter what you do though, merging updates will be inherently brittle. That is, unless the author of the third party page is consciously presenting some form of a stable API.
You can perhaps use Reflection Emit to inject code into the code behind class in app start-up.
Is there a quick and dirty way of using a query passed as follows:
domain.com/mypage.aspx/product/toycar/
I've done it before in PHP, but this needs to be done in page (in this instance).
--
I only have access to the aspx page and code behind, and have to work in asp.net 2 (i wish i was using 3.5)
quick and dirty:
public class ModuleRewriter : IHttpModule
{
public void Init(HttpApplication application)
{
application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
}
private void Application_BeginRequest(Object source, EventArgs e)
{
// The url will look like: http://domain.com/mypage.aspx/product/toycar/
// The module will rewrite it to: http://domain.com/mypage.aspx?product=toycar
HttpApplication application = source as HttpApplication;
string[] urlInfo = application.Request.RawUrl.ToString().Split('/');
if (urlInfo.Length > 2)
{
string page = urlInfo[urlInfo.Length - 3];
string action = urlInfo[urlInfo.Length - 2];
string id = urlInfo[urlInfo.Length - 1];
if (string.IsNullOrEmpty(page))
{
page = "default.aspx";
}
application.Server.Transfer(string.Format(
"~/{0}?{1}={2}", page, action, id));
}
}
public void Dispose()
{
}
}
web.config:
<httpModules>
<add name="ModuleRewriter" type="ModuleRewriter, MyWebApplication"/>
</httpModules>
and a test page:
<%# Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<%= Request["product"] %>
</div>
</form>
</body>
</html>
You might want to look into the ASP.NET System.Web.Routing namespace, which was added in .NET 3.5 SP1 I believe:
http://blogs.msdn.com/mikeormond/archive/2008/05/14/using-asp-net-routing-independent-of-mvc.aspx
http://msdn.microsoft.com/en-us/library/system.web.routing.aspx
You'd be able to get rid of the .aspx extension too.
This would involve making a custom HTTP Handler.
Check this
You've got a few options, but all of them require access to the web.config and a change to IIS to map all file extensions to the dotNet ISAPI dll:
Use MVC (like stackoverflow does,
notice the urls)
Use asp.net routing (new in 3.5)
Write your own http handler Massive guide from Microsoft here
Use the excellent urlrewriting.net which does just about everything perfectly including getting round some awkward authentication and image path problems.
Personally I used urlrewriting.net with good results.
Since you mention you don't have access to anything but the code behind and the page, the only thing I can think of is actually creating those dirs (if you have access to do that) and using a server.transfer page passing the value to your actual page in the folder above. Messy, but if you can't access the other stuff, your choices are limited.
In case you just want to read the path from within your .aspx:
Request.ServerVariables["PATH_INFO"]
To clarify:
he has only access to the aspx (+ codebehind) itself, so he must know how the query is, but it is not in the Request.QueryString because of the format. So the only way then is Request.ServerVariables["PATH_INFO"] (Request.RawUrl)