Dec 30 2011

Simple ASP.NET MVC script manager

Category: ASP.NET | C# | MVC3 — Duke @ 15:57

I remember that some months ago I’ve found a beauty video of a beauty component that allows to manage .js and .css files from an MVC application.

Unfortunately I’ve lost the link and I don’t remember the name of the component.

I’ve searched the seven seas of the internet but… nothing. Things went worst today when I realized I need a script manager.

I’ve searched, browsed and digged the internet again but the best I’ve found is the “Simple script manager” on codeplex, that is well far from being “beauty”

So, I’ve started my own simple script manager. for now it is very basic. it does almost nothing but at least it is in full “MVC” style, by using and respecting the existing design of MVC3, differently from the other things I’ve found.

 

so: here is the code

 

namespace Web.Helpers
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Web.Mvc;
    using System.Web.WebPages;

    /// <summary>
    /// Provides a way to declare in any place of cshtml pages the required .css and .js, they will be generated later in the _layout page
    /// </summary>
    public static class FileHelper
    {

        /// <summary>
        /// Requires a file to be referenced
        /// </summary>
        /// <param name="helper">the Html helper this method extends</param>
        /// <param name="resource">the path to the resource</param>
        /// <returns>null</returns>
        /// <remarks>the extension of the file .css or .js allows the method to decide wich tag should be generated
        /// this method may affect the AdditionalScripts and the AdditionalStyles property in the ViewBag</remarks>
        public static object Require(this HtmlHelper helper, string resource)
        {
            if (!Path.HasExtension(resource)) throw new ArgumentException("Impossible to determine the file type as it doesn't have extension");
            if (Path.GetExtension(resource).Equals(".css", StringComparison.InvariantCultureIgnoreCase))
            {
                return RequireCss(helper, resource);                
            }
            if (Path.GetExtension(resource).Equals(".js", StringComparison.InvariantCultureIgnoreCase))
            {
                return RequireJs(helper, resource);                
            }
            throw new ArgumentException("Only .js and .css are supported");
        }

        /// <summary>
        /// Requires a javascript script file to be referenced
        /// </summary>
        /// <param name="helper">the Html helper this method extends</param>
        /// <param name="resource">the path to the script</param>
        /// <returns>null</returns>
        /// <remarks>this method affects the AdditionalScripts property in the ViewBag</remarks>
        public static object RequireJs(this HtmlHelper helper, string script)
        {
            HashSet<string> requiredScript = GetScriptTable(helper);

            if (!requiredScript.Contains(script))
            {
                requiredScript.Add(script);
            }

            return null;
        }

        /// <summary>
        /// Requires a css script file to be referenced
        /// </summary>
        /// <param name="helper">the Html helper this method extends</param>
        /// <param name="resource">the path to the script</param>
        /// <returns>null</returns>
        /// <remarks>this method affects the AdditionalScripts property in the ViewBag</remarks>
        public static object RequireCss(this HtmlHelper helper, string style)
        {
            HashSet<string> requiredStyle = GetStyleTable(helper);

            if (!requiredStyle.Contains(style))
            {
                requiredStyle.Add(style);
            }

            return null;
        }

        private static HashSet<string> GetScriptTable(HtmlHelper helper)
        {
            HashSet<string> requiredScripts;
            if (helper.ViewContext.Controller.ViewBag.AdditionalScripts == null)
            {
                requiredScripts = new HashSet<string>();
                helper.ViewContext.Controller.ViewBag.AdditionalScripts = requiredScripts;
            }
            else
            {
                requiredScripts = helper.ViewContext.Controller.ViewBag.AdditionalScripts;
            }
            return requiredScripts;
        }

        private static HashSet<string> GetStyleTable(HtmlHelper helper)
        {
            HashSet<string> requiredStyles;
            if (helper.ViewContext.Controller.ViewBag.AdditionalStyles == null)
            {
                requiredStyles = new HashSet<string>();
                helper.ViewContext.Controller.ViewBag.AdditionalStyles = requiredStyles;
            }
            else
            {
                requiredStyles = helper.ViewContext.Controller.ViewBag.AdditionalStyles;
            }
            return requiredStyles;
        }

        /// <summary>
        /// renders the tag to reference the required javascripts
        /// </summary>
        /// <param name="helper">the HtmlHelper this method extends</param>
        /// <returns>a set of tags that represents the required javascripts</returns>
        public static HelperResult RenderRequiredJs(this HtmlHelper helper)
        {
            return new HelperResult(writer => GenerateAllScriptsTags(writer, GetScriptTable(helper)));
        }

        private static void GenerateAllScriptsTags(TextWriter writer, HashSet<string> requests)
        {
            if (requests == null) return;
            foreach (var script in requests)
            {                
                var builder = new TagBuilder("script");
                builder.Attributes.Add("src", script);
                builder.Attributes.Add("type", "text/javascript");
                writer.WriteLine(builder.ToString(TagRenderMode.Normal));
            }            
        }

        /// <summary>
        /// renders the tag to reference the required css
        /// </summary>
        /// <param name="helper">the HtmlHelper this method extends</param>
        /// <returns>a set of tags that represents the required styles sheets</returns>
        public static HelperResult RenderRequiredCss(this HtmlHelper helper)
        {
            return new HelperResult(writer => GenerateAllStylesTags(writer, GetStyleTable(helper)));
        }

        private static void GenerateAllStylesTags(TextWriter writer, HashSet<string> requests)
        {
            if (requests == null) return;
            foreach (var style in requests)
            {                
                var builder = new TagBuilder("link");
                builder.Attributes.Add("href", style);
                builder.Attributes.Add("rel", "stylesheet");
                builder.Attributes.Add("type", "text/css");
                writer.WriteLine(builder.ToString(TagRenderMode.SelfClosing));
            }
        }

        /// <summary>
        /// renders the tags to reference the required javascripts and css
        /// </summary>
        /// <param name="helper">the HtmlHelper this method extends</param>
        /// <returns>a set of tags that represents the required javascripts and css</returns>
        public static HelperResult RenderRequiredFiles(this HtmlHelper helper)
        {
            return new HelperResult(writer => 
            {
                GenerateAllStylesTags(writer, GetStyleTable(helper));
                GenerateAllScriptsTags(writer, GetStyleTable(helper));
            });
        }
    }
}

and with this I can write in my pages things like

@Html.Require(Url.Content("~/Content/tinymce/tinymce.css"))
@Html.Require(Url.Content("~/Scripts/jquery.validate.min.js"))
@Html.Require(Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js"))

and finally render the required tag in the _Layout.cshtml by writing

@Html.RenderRequiredFiles()

And forgetting about the rest.

I like MVC because it is very easy to extend!

Tags: , ,

1.
Wholesale Jerseys China Wholesale Jerseys China says:

We acquire elite the somebody Nike wholesale nfl jerseys usa Knockoffs is healthier and cheaper here then. Fewer steps, at least in all parts of the world. It is clear that the Air Pegasus shoe series has always been popular. Once this technology has proved itself, Nike designers returned to the whole palm gasbag design, and this actually began in 1997. They've released the Foamposite, 1/2 Cent, and wholesale nfl jerseys usa unit at heel is for maximum impact, together with the envisioned visual appeal linked with December 30 very first.

Take a look at my website ...  Wholesale Jerseys China - http://highway11.com

2.
Kristin Kristin says:

Wow! This blog looks exactly like my old one! It's on a completely different subject but it has pretty much the same page layout and design. Wonderful choice of colors!

My website - how to do business online [ Kristin - http://mycashtown.com/ ]

3.
Lilly Lilly says:

I got this site from my buddy who shared with me on the topic of this site and now this time I am browsing this site and reading very informative articles here.

Stop by my page - Symptome einer Uberstimulation der Ovarien ::  Lilly - http://lamedecinefrancaise.com/kaufen-clomid-ch-1/  ::

4.
tarot divinatoire tarot divinatoire says:

Voyance gratuite en direct sur internet stripping  horoscope en arabe 2011

Feel free to surf to my webpage;  tarot divinatoire - http://www.bartlatjes.com

Add comment

  Country flag

biuquote
  • Comment
  • Preview
Loading