using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.Ajax.Utilities;
using System.Configuration;
using System.IO;
using System.IO.Compression;
namespace mvcDemo.Controllers
{
public class FileBundlerController : Controller
{
private static readonly string staticFileRoot = ConfigurationManager.AppSettings["staticFileRoot"];
private static readonly string staticFileCatchRoot = ConfigurationManager.AppSettings["staticFileCatchRoot"];
//
// GET: /FileBundler/
// url格式:host/Controller?[type=类型(js、css)href=文件地址(以;分隔)](可以有多个目录)&t=版本
// demoUrl: http://localhost:4122/FileBundler?type=js&href=js.;admin_common,content_addtop.min&t=2010-10-29_19:16:18
public string Index()
{
string urlQuery = Request.Url.Query;
if (string.IsNullOrWhiteSpace(urlQuery))
{
return "参数错误!!!";
}
string[] paramList = urlQuery.Substring(1).Split('&');
/**
* 必须是三个参数type、href、t
* **/
if (paramList.Length != 3)
{
return "参数错误!!!";
}
Dictionary<string, string> urlParam = new Dictionary<string, string>();
foreach (string item in paramList)
{
string[] paramItem = item.Split('=');
/**
* 各参数以=分隔
* **/
if (paramItem.Length != 2)
{
return "参数错误!!!";
}
/**
* 参数不能重复
* **/
if (urlParam.ContainsKey(paramItem[0]))
{
return "参数错误!!!";
}
urlParam.Add(paramItem[0], paramItem[1]);
}
/**
* 三个参数必须是固定的
* **/
if (!urlParam.ContainsKey("type") || !urlParam.ContainsKey("href") || !urlParam.ContainsKey("t"))
{
return "参数错误!!!";
}
string fileType = urlParam["type"];
string href = urlParam["href"];
/**
* 不参包含/或\(文件名里不能有/或\)
* **/
if (href.Contains("/") || href.Contains(@"\"))
{
return "参数错误!!!";
}
string fileName = string.Format("{0}{1}.{2}", staticFileCatchRoot, href, fileType);
/**
* 类型必须为js或css
* **/
if (fileType.Equals("js"))
{
Response.ContentType = "text/javascript";
}
else if (fileType.Equals("css"))
{
Response.ContentType = "text/css";
}
else
{
return "参数错误!!!";
}
DateTime versionTime = DateTime.MinValue;
try
{
versionTime = DateTime.Parse(urlParam["t"].Replace("_", " "));
}
catch{}
/**
* 时间转换出错会执行这里
* **/
if(versionTime == DateTime.MinValue)
{
return "参数错误!!!";
}
System.IO.FileInfo fileInfo = null;
if (System.IO.File.Exists(fileName))
{
fileInfo = new FileInfo(fileName);
if (fileInfo.CreationTime == versionTime)
{
return System.IO.File.ReadAllText(fileName);
}
}
/**
* 多个目录以;分隔
* **/
string[] hrefParam = href.Split(';');
int hrefParamLen = hrefParam.Length;
/**
* 目录和文件是以;分隔,所以目录+文件的个数是2的倍数
* **/
if (hrefParamLen % 2 != 0)
{
return "参数错误!!!";
}
StringBuilder content = new StringBuilder();
for (int i = 0; i < hrefParamLen; i++)
{
string folder = hrefParam[i].Replace(".","/");
folder = string.Format("{0}{1}", staticFileRoot, folder);
string[] files = hrefParam[++i].Split(',');
foreach (string item in files)
{
string _fileName = string.Format("{0}{1}.{2}", folder, item, fileType);
/**
* 文件不存在,输出错误信息
* **/
if (!System.IO.File.Exists(_fileName))
{
return "文件未找到!!!";
}
content.Append(System.IO.File.ReadAllText(_fileName));
}
}
string fileContent = Minify(content.ToString(), string.Format(".{0}",fileType));
System.IO.File.WriteAllText(fileName, fileContent);
fileInfo = new FileInfo(fileName);
fileInfo.CreationTime = versionTime;
return fileContent;
}
private static string Minify(string content, string extension)
{
Minifier cruncher = new Minifier();
if (extension == ".js")
{
CodeSettings settings = new CodeSettings
{
EvalTreatment = EvalTreatment.MakeImmediateSafe,
MinifyCode = true,
RemoveUnneededCode = true,
LocalRenaming = LocalRenaming.CrunchAll,
RemoveFunctionExpressionNames = true
};
return cruncher.MinifyJavaScript(content, settings);
}
else if (extension == ".css")
{
return cruncher.MinifyStyleSheet(content);
}
return content;
}
}
}
MVC4引入:WebGrease.dll
其它项目引入:AjaxMin.dll 下载地址:http://ajaxmin.codeplex.com
