Skip to content

Instantly share code, notes, and snippets.

@dinowang
Last active November 28, 2015 14:58
Show Gist options
  • Save dinowang/c29551fb8ef8c2fdff56 to your computer and use it in GitHub Desktop.
Save dinowang/c29551fb8ef8c2fdff56 to your computer and use it in GitHub Desktop.
ScriptalizedOutputAttribute
<ul>
<li></li>
<li></li>
</ul>
public class AdController : ControllerBase
{
[ScriptalizedOutput]
public ActionResult StackBanner()
{
// ...
return View(); // 這裡還是單純 render HTML 就好
}
}
document.write("<ul><li></li><li></li></ul>");
<script type="type/javascript" src="http://test-server/Ad/StackBanner"></script>
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("&lt;script type=\"text/javascript\"&gt;\n//&lt;!--\ndocument.write(\"{0}\");\n//--&gt;\n&lt;/script&gt;", 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