Last active
November 28, 2015 14:58
-
-
Save dinowang/c29551fb8ef8c2fdff56 to your computer and use it in GitHub Desktop.
ScriptalizedOutputAttribute
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class AdController : ControllerBase | |
{ | |
[ScriptalizedOutput] | |
public ActionResult StackBanner() | |
{ | |
// ... | |
return View(); // 這裡還是單純 render HTML 就好 | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
document.write("<ul><li></li><li></li></ul>"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script type="type/javascript" src="http://test-server/Ad/StackBanner"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ScriptalizedOutputAttribute : ActionFilterAttribute | |
{ | |
public bool WrapScriptTag { get; set; } | |
public override void OnActionExecuting(ActionExecutingContext filterContext) | |
{ | |
} | |
public override void OnActionExecuted(ActionExecutedContext filterContext) | |
{ | |
var response = filterContext.HttpContext.Response; | |
response.Filter = new StreamFilter(response.Filter, s => | |
{ | |
s = Regex.Replace(s, @"(\r\n|\n|\r)", "\\n"); // 換行字元都改掉 | |
s = Regex.Replace(s, @"\""", "\\\""); // 要考慮逸出字元 | |
if (WrapScriptTag) | |
{ | |
return string.Format("<script type=\"text/javascript\">\n//<!--\ndocument.write(\"{0}\");\n//-->\n</script>", s); | |
} | |
return string.Format("document.write(\"{0}\");", s); | |
}); | |
response.ContentType = "text/javascript"; | |
} | |
class StreamFilter : Stream | |
{ | |
private Stream _shrink; | |
private Func<string, string> _filter; | |
public StreamFilter(Stream shrink, Func<string, string> filter) | |
{ | |
_shrink = shrink; | |
_filter = filter; | |
} | |
public override bool CanRead { get { return true; } } | |
public override bool CanSeek { get { return true; } } | |
public override bool CanWrite { get { return true; } } | |
public override void Flush() { _shrink.Flush(); } | |
public override long Length { get { return 0; } } | |
public override long Position { get; set; } | |
public override int Read(byte[] buffer, int offset, int count) | |
{ | |
return _shrink.Read(buffer, offset, count); | |
} | |
public override long Seek(long offset, SeekOrigin origin) | |
{ | |
return _shrink.Seek(offset, origin); | |
} | |
public override void SetLength(long value) | |
{ | |
_shrink.SetLength(value); | |
} | |
public override void Close() | |
{ | |
_shrink.Close(); | |
} | |
public override void Write(byte[] buffer, int offset, int count) | |
{ | |
// capture the data and convert to string | |
byte[] data = new byte[count]; | |
Buffer.BlockCopy(buffer, offset, data, 0, count); | |
string s = Encoding.UTF8.GetString(buffer); | |
// filter the string | |
s = _filter(s); | |
// write the data to stream | |
byte[] outdata = Encoding.UTF8.GetBytes(s); | |
_shrink.Write(outdata, 0, outdata.GetLength(0)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment