Собираем статические файлы в dll (asp.net mvc)

Для того, чтобы статические файлы можно было собрать в отдельную библиотеку, нужно у этих файлов поставить свойство «Build Action» в значение «Embedded Resource». После того как все файлы будут находится в отдельной сборке, нужно научить приложение доставать эти файлы из dll.

Пусть все статические файлы находятся в папке Content. Например javacript файлы в папке /Content/JS, стили в папке /Content/CSS и тд.
Тогда если файлы не будут «Embedded Resource», то обращаться к ним можно будет обычным образом: /Content/JS/Test.js или /Content/CSS/Test.css. А если файлы будут «Embedded Resource», то сделаем к ним доступ таким образом /Resources/JS/Test.js или /Resources/CSS/Test.css.  Приступим!

Для начала напишем http обработчик:


public class EmbeddedResourceHttpHandler : IHttpHandler
{
    private RouteData _routeData;

    public EmbeddedResourceHttpHandler(RouteData routeData)
    {
        _routeData = routeData;
    }
    public bool IsReusable
    {
        get { return false; }
    }
    public void ProcessRequest(HttpContext context)
    {
        var routeDataValues = _routeData.Values;
        var pathInfo = routeDataValues["pathInfo"].ToString();

        string nameSpace = typeof(EmbeddedResourceHttpHandler).Assembly.GetName().Name;
        string manifestResourceName = string.Format("{0}.Content.{1}", nameSpace, pathInfo.Replace('/', '.'));
        var stream = typeof(EmbeddedResourceHttpHandler).Assembly.GetManifestResourceStream(manifestResourceName);

        string fileExtension = Path.GetExtension(pathInfo);

        context.Response.Clear();
        if (fileExtension == ".js")
            context.Response.ContentType = "text/javascript";
        else if (fileExtension == ".css")
            context.Response.ContentType = "text/css";
        else
            throw new ArgumentException();
        stream.CopyTo(context.Response.OutputStream);
    }

}

Затем создадим для этого обработчика свой route обработчик:

public class EmbeddedResourceRouteHandler : IRouteHandler
{
    IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext)
    {
        return new EmbeddedResourceHttpHandler(requestContext.RouteData);
    }
    public static void RegisterRouteHandler()
    {
        RouteTable.Routes.Insert(0,
            new Route("Resources/{*pathInfo}",
            new RouteValueDictionary(new { }),
            new RouteValueDictionary(new { }),
            new EmbeddedResourceRouteHandler()
        ));
    }
}

В web.config пропишем следующие строчки

<system.webServer>
    <handlers>
        <add name="content" path="/Resources/*" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
</system.webServer>

В global.asax добавим такую строчку

EmbeddedResourceRouteHandler.RegisterRouteHandler();