Asp.net mvc 4 TinyMCE ashx从IIS7获取404错误
我有一个ASP.NETMVC4项目。如果我想让TinyMCE使用gzip,我需要在我的页面中使用以下内容,例如:Asp.net mvc 4 TinyMCE ashx从IIS7获取404错误,asp.net-mvc-4,iis-7,tinymce,ashx,Asp.net Mvc 4,Iis 7,Tinymce,Ashx,我有一个ASP.NETMVC4项目。如果我想让TinyMCE使用gzip,我需要在我的页面中使用以下内容,例如: <script type="text/javascript" src="/Scripts/tiny_mce/tiny_mce_gzip.js"></script> <script type="text/javascript"> tinyMCE_GZ.init({ plugins: 'style,layer,table,sav
<script type="text/javascript" src="/Scripts/tiny_mce/tiny_mce_gzip.js"></script>
<script type="text/javascript">
tinyMCE_GZ.init({
plugins: 'style,layer,table,save,advhr,advimage,advlink,emotions,iespell,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras',
themes: 'simple,advanced',
languages: 'en',
disk_cache: true,
debug: false
});
</script>
ashx文件确实存在于相应的文件夹中,但由于某些原因,IIS不会为其提供服务。我尝试添加以下路由处理程序,但两者都没有任何区别:
routes.IgnoreRoute("{resource}.ashx/{*pathInfo}");
routes.IgnoreRoute("{*allashx}", new { allashx = @".*\.ashx(/.*)?" });
解决
浏览过互联网后,我发现有很多人都有同样的问题,似乎没有人找到解决办法!甚至在TinyMCE支持页面上。因此,我提出了一个解决方案,我希望它不会被诅咒:
唯一需要配置的是Global.asax中的TinyMceScriptFolder变量-它必须指向TinyMCE scripts文件夹duh确保该路径不以/开头,否则路由处理程序将拒绝它。在任何情况下,它都将从站点的根目录开始工作
TinyMCEGzipHandler.cs是从原始的.ashx文件复制的,但添加了一些内容
using System;
using System.Web;
using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using Property;
namespace Softwarehouse.TinyMCE
{
public class GzipHandler : IHttpHandler
{
private HttpResponse Response;
private HttpRequest Request;
private HttpServerUtility Server;
public void ProcessRequest(HttpContext context)
{
this.Response = context.Response;
this.Request = context.Request;
this.Server = context.Server;
this.StreamGzipContents();
}
public bool IsReusable
{
get { return false; }
}
#region private
private void StreamGzipContents()
{
string cacheKey = "", cacheFile = "", content = "", enc, suffix, cachePath;
string[] plugins, languages, themes;
bool diskCache, supportsGzip, isJS, compress, core;
int i, x, expiresOffset;
GZipStream gzipStream;
Encoding encoding = Encoding.GetEncoding("windows-1252");
byte[] buff;
// Get input
plugins = GetParam("plugins", "").Split(',');
languages = GetParam("languages", "").Split(',');
themes = GetParam("themes", "").Split(',');
diskCache = GetParam("diskcache", "") == "true";
isJS = GetParam("js", "") == "true";
compress = GetParam("compress", "true") == "true";
core = GetParam("core", "true") == "true";
suffix = GetParam("suffix", "") == "_src" ? "_src" : "";
cachePath = Server.MapPath("/" + MvcApplication.TinyMceScriptFolder); // Cache path, this is where the .gz files will be stored
expiresOffset = 10; // Cache for 10 days in browser cache
// Custom extra javascripts to pack
string[] custom =
{
/*
"some custom .js file",
"some custom .js file"
*/
};
// Set response headers
Response.ContentType = "text/javascript";
Response.Charset = "UTF-8";
Response.Buffer = false;
// Setup cache
Response.Cache.SetExpires(DateTime.Now.AddDays(expiresOffset));
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetValidUntilExpires(false);
// Vary by all parameters and some headers
Response.Cache.VaryByHeaders["Accept-Encoding"] = true;
Response.Cache.VaryByParams["theme"] = true;
Response.Cache.VaryByParams["language"] = true;
Response.Cache.VaryByParams["plugins"] = true;
Response.Cache.VaryByParams["lang"] = true;
Response.Cache.VaryByParams["index"] = true;
// Is called directly then auto init with default settings
if (!isJS)
{
Response.WriteFile(Server.MapPath("/" + MvcApplication.TinyMceScriptFolder + "/tiny_mce_gzip.js"));
Response.Write("tinyMCE_GZ.init({});");
return;
}
// Setup cache info
if (diskCache)
{
cacheKey = GetParam("plugins", "") + GetParam("languages", "") + GetParam("themes", "");
for (i = 0; i < custom.Length; i++)
cacheKey += custom[i];
cacheKey = MD5(cacheKey);
if (compress)
cacheFile = cachePath + "/tiny_mce_" + cacheKey + ".gz";
else
cacheFile = cachePath + "/tiny_mce_" + cacheKey + ".js";
}
// Check if it supports gzip
enc = Regex.Replace("" + Request.Headers["Accept-Encoding"], @"\s+", "").ToLower();
supportsGzip = enc.IndexOf("gzip") != -1 || Request.Headers["---------------"] != null;
enc = enc.IndexOf("x-gzip") != -1 ? "x-gzip" : "gzip";
// Use cached file disk cache
if (diskCache && supportsGzip && File.Exists(cacheFile))
{
Response.AppendHeader("Content-Encoding", enc);
Response.WriteFile(cacheFile);
return;
}
// Add core
if (core)
{
content += GetFileContents("tiny_mce" + suffix + ".js");
// Patch loading functions
content += "tinyMCE_GZ.start();";
}
// Add core languages
for (x = 0; x < languages.Length; x++)
content += GetFileContents("langs/" + languages[x] + ".js");
// Add themes
for (i = 0; i < themes.Length; i++)
{
content += GetFileContents("themes/" + themes[i] + "/editor_template" + suffix + ".js");
for (x = 0; x < languages.Length; x++)
content += GetFileContents("themes/" + themes[i] + "/langs/" + languages[x] + ".js");
}
// Add plugins
for (i = 0; i < plugins.Length; i++)
{
content += GetFileContents("plugins/" + plugins[i] + "/editor_plugin" + suffix + ".js");
for (x = 0; x < languages.Length; x++)
content += GetFileContents("plugins/" + plugins[i] + "/langs/" + languages[x] + ".js");
}
// Add custom files
for (i = 0; i < custom.Length; i++)
content += GetFileContents(custom[i]);
// Restore loading functions
if (core)
content += "tinyMCE_GZ.end();";
// Generate GZIP'd content
if (supportsGzip)
{
if (compress)
Response.AppendHeader("Content-Encoding", enc);
if (diskCache && cacheKey != "")
{
// Gzip compress
if (compress)
{
using (Stream fileStream = File.Create(cacheFile))
{
gzipStream = new GZipStream(fileStream, CompressionMode.Compress, true);
buff = encoding.GetBytes(content.ToCharArray());
gzipStream.Write(buff, 0, buff.Length);
gzipStream.Close();
}
}
else
{
using (StreamWriter sw = File.CreateText(cacheFile))
{
sw.Write(content);
}
}
// Write to stream
Response.WriteFile(cacheFile);
}
else
{
gzipStream = new GZipStream(Response.OutputStream, CompressionMode.Compress, true);
buff = encoding.GetBytes(content.ToCharArray());
gzipStream.Write(buff, 0, buff.Length);
gzipStream.Close();
}
}
else
Response.Write(content);
}
private string GetParam(string name, string def)
{
string value = Request.QueryString[name] != null ? "" + Request.QueryString[name] : def;
return Regex.Replace(value, @"[^0-9a-zA-Z\\-_,]+", "");
}
private string GetFileContents(string path)
{
try
{
string content;
path = Server.MapPath("/" + MvcApplication.TinyMceScriptFolder + "/" + path);
if (!File.Exists(path))
return "";
StreamReader sr = new StreamReader(path);
content = sr.ReadToEnd();
sr.Close();
return content;
}
catch (Exception ex)
{
// Ignore any errors
}
return "";
}
private string MD5(string str)
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] result = md5.ComputeHash(Encoding.ASCII.GetBytes(str));
str = BitConverter.ToString(result);
return str.Replace("-", "");
}
#endregion
}
}
Web.config
using System;
using System.Web;
using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using Property;
namespace Softwarehouse.TinyMCE
{
public class GzipHandler : IHttpHandler
{
private HttpResponse Response;
private HttpRequest Request;
private HttpServerUtility Server;
public void ProcessRequest(HttpContext context)
{
this.Response = context.Response;
this.Request = context.Request;
this.Server = context.Server;
this.StreamGzipContents();
}
public bool IsReusable
{
get { return false; }
}
#region private
private void StreamGzipContents()
{
string cacheKey = "", cacheFile = "", content = "", enc, suffix, cachePath;
string[] plugins, languages, themes;
bool diskCache, supportsGzip, isJS, compress, core;
int i, x, expiresOffset;
GZipStream gzipStream;
Encoding encoding = Encoding.GetEncoding("windows-1252");
byte[] buff;
// Get input
plugins = GetParam("plugins", "").Split(',');
languages = GetParam("languages", "").Split(',');
themes = GetParam("themes", "").Split(',');
diskCache = GetParam("diskcache", "") == "true";
isJS = GetParam("js", "") == "true";
compress = GetParam("compress", "true") == "true";
core = GetParam("core", "true") == "true";
suffix = GetParam("suffix", "") == "_src" ? "_src" : "";
cachePath = Server.MapPath("/" + MvcApplication.TinyMceScriptFolder); // Cache path, this is where the .gz files will be stored
expiresOffset = 10; // Cache for 10 days in browser cache
// Custom extra javascripts to pack
string[] custom =
{
/*
"some custom .js file",
"some custom .js file"
*/
};
// Set response headers
Response.ContentType = "text/javascript";
Response.Charset = "UTF-8";
Response.Buffer = false;
// Setup cache
Response.Cache.SetExpires(DateTime.Now.AddDays(expiresOffset));
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetValidUntilExpires(false);
// Vary by all parameters and some headers
Response.Cache.VaryByHeaders["Accept-Encoding"] = true;
Response.Cache.VaryByParams["theme"] = true;
Response.Cache.VaryByParams["language"] = true;
Response.Cache.VaryByParams["plugins"] = true;
Response.Cache.VaryByParams["lang"] = true;
Response.Cache.VaryByParams["index"] = true;
// Is called directly then auto init with default settings
if (!isJS)
{
Response.WriteFile(Server.MapPath("/" + MvcApplication.TinyMceScriptFolder + "/tiny_mce_gzip.js"));
Response.Write("tinyMCE_GZ.init({});");
return;
}
// Setup cache info
if (diskCache)
{
cacheKey = GetParam("plugins", "") + GetParam("languages", "") + GetParam("themes", "");
for (i = 0; i < custom.Length; i++)
cacheKey += custom[i];
cacheKey = MD5(cacheKey);
if (compress)
cacheFile = cachePath + "/tiny_mce_" + cacheKey + ".gz";
else
cacheFile = cachePath + "/tiny_mce_" + cacheKey + ".js";
}
// Check if it supports gzip
enc = Regex.Replace("" + Request.Headers["Accept-Encoding"], @"\s+", "").ToLower();
supportsGzip = enc.IndexOf("gzip") != -1 || Request.Headers["---------------"] != null;
enc = enc.IndexOf("x-gzip") != -1 ? "x-gzip" : "gzip";
// Use cached file disk cache
if (diskCache && supportsGzip && File.Exists(cacheFile))
{
Response.AppendHeader("Content-Encoding", enc);
Response.WriteFile(cacheFile);
return;
}
// Add core
if (core)
{
content += GetFileContents("tiny_mce" + suffix + ".js");
// Patch loading functions
content += "tinyMCE_GZ.start();";
}
// Add core languages
for (x = 0; x < languages.Length; x++)
content += GetFileContents("langs/" + languages[x] + ".js");
// Add themes
for (i = 0; i < themes.Length; i++)
{
content += GetFileContents("themes/" + themes[i] + "/editor_template" + suffix + ".js");
for (x = 0; x < languages.Length; x++)
content += GetFileContents("themes/" + themes[i] + "/langs/" + languages[x] + ".js");
}
// Add plugins
for (i = 0; i < plugins.Length; i++)
{
content += GetFileContents("plugins/" + plugins[i] + "/editor_plugin" + suffix + ".js");
for (x = 0; x < languages.Length; x++)
content += GetFileContents("plugins/" + plugins[i] + "/langs/" + languages[x] + ".js");
}
// Add custom files
for (i = 0; i < custom.Length; i++)
content += GetFileContents(custom[i]);
// Restore loading functions
if (core)
content += "tinyMCE_GZ.end();";
// Generate GZIP'd content
if (supportsGzip)
{
if (compress)
Response.AppendHeader("Content-Encoding", enc);
if (diskCache && cacheKey != "")
{
// Gzip compress
if (compress)
{
using (Stream fileStream = File.Create(cacheFile))
{
gzipStream = new GZipStream(fileStream, CompressionMode.Compress, true);
buff = encoding.GetBytes(content.ToCharArray());
gzipStream.Write(buff, 0, buff.Length);
gzipStream.Close();
}
}
else
{
using (StreamWriter sw = File.CreateText(cacheFile))
{
sw.Write(content);
}
}
// Write to stream
Response.WriteFile(cacheFile);
}
else
{
gzipStream = new GZipStream(Response.OutputStream, CompressionMode.Compress, true);
buff = encoding.GetBytes(content.ToCharArray());
gzipStream.Write(buff, 0, buff.Length);
gzipStream.Close();
}
}
else
Response.Write(content);
}
private string GetParam(string name, string def)
{
string value = Request.QueryString[name] != null ? "" + Request.QueryString[name] : def;
return Regex.Replace(value, @"[^0-9a-zA-Z\\-_,]+", "");
}
private string GetFileContents(string path)
{
try
{
string content;
path = Server.MapPath("/" + MvcApplication.TinyMceScriptFolder + "/" + path);
if (!File.Exists(path))
return "";
StreamReader sr = new StreamReader(path);
content = sr.ReadToEnd();
sr.Close();
return content;
}
catch (Exception ex)
{
// Ignore any errors
}
return "";
}
private string MD5(string str)
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] result = md5.ComputeHash(Encoding.ASCII.GetBytes(str));
str = BitConverter.ToString(result);
return str.Replace("-", "");
}
#endregion
}
}
public const string TinyMceScriptFolder = "Scripts/htmleditor";
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute(TinyMceScriptFolder + "/tiny_mce_gzip.ashx");
}
<system.webServer>
<httpHandlers>
<add name="TinyMCEGzip" verb="GET" path="tiny_mce_gzip.ashx" type="Softwarehouse.TinyMCE.GzipHandler"/>
</httpHandlers>
</system.webServer>