HttpResponse.Filter 在 MVC 6/vNext 中?
HttpResponse.Filter in MVC 6 / vNext?
我正在开发一个网站框架,该框架使用 "Widgets" 在 portal/portlet 类型的网站内呈现内容块。基本上是 Wordpress 如何让您自定义网站的一个非常简短的版本。
经过搜索但未能找到任何现有框架,看来最合理的实现方式是使用 MVC 的 "Partial Views" 功能。
我希望能够完全封装每个 "widget" 而不必在宿主视图中重复脚本或样式标签(视图不需要知道任何有关如何呈现小部件的信息)。
为实现这一点,任何脚本引用都由 Widget Partial View 存储,然后在 View 呈现其自己的脚本部分时注入。在一个实例中,这是使用响应过滤器实现的。
我正在通过 CoreCLR 使用 MVC 6 (vNext),并且正在尝试确定如何在新框架下实现此过滤器位。似乎 HttpResponse 对象不再具有 "Filter" 字段。
你能告诉我这在新框架下如何运作吗?
/// <summary>
/// Appends partial view scripts to the html response of an AJAX request
/// </summary>
public class RenderAjaxPartialScriptsAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
var response = filterContext.HttpContext.Response;
if (response.Filter != null)
response.Filter = new RenderAjaxPartialScriptsResponseFilter(response.Filter, filterContext);
}
}
}
原始代码来自 Ryan Burnham 的博客 https://rburnham.wordpress.com/2015/03/13/asp-net-mvc-defining-scripts-in-partial-views/#comment-2286
您可以通过在 Startup.cs
中使用 Middleware
来实现:
快捷方式:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
////
app.Use(async (httpContext, next) =>
{
await next();
// if is ajax request
if (httpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
// if succesful status code
if (httpContext.Response.StatusCode == 200)
{
// you can get scripts data from httpContext.Items[key] and build html
string html = "<script src='~/js/script-demo.js'></script>";
using (var writeResponseStream = new StreamWriter(httpContext.Response.Body))
{
// write html to response body
await writeResponseStream.WriteAsync(html);
}
}
}
});
// Add MVC to the request pipeline.
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
正确的方法:
中间件实现:
public class AjaxScriptInjectorMiddleware
{
private readonly RequestDelegate _next;
public AjaxScriptInjectorMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
await _next.Invoke(context);
// if is ajax request
if (IsAjax(context.Request))
{
// if succesful status code
if (IsSuccess(context.Response.StatusCode))
{
// you can get scripts data from context.Items[key] and build html
string html = "<script src='~/js/script-demo.js'></script>";
using(var writeResponseStream = new StreamWriter(context.Response.Body))
{
// write html to response body
await writeResponseStream.WriteAsync(html);
}
}
}
}
private bool IsAjax(HttpRequest request)
{
return request.Headers["X-Requested-With"] == "XMLHttpRequest";
}
private bool IsSuccess(int statusCode)
{
return statusCode >= 200 && statusCode <= 299;
}
}
IApplicationBuilder
扩展方法:
public static class AjaxScriptInjectorExtensions
{
public static IApplicationBuilder UseAjaxScriptInjector(this IApplicationBuilder builder)
{
return builder.UseMiddleware<AjaxScriptInjectorMiddleware>();
}
}
使用middleware
:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// use custom ajax script injector middleware
app.UseAjaxScriptInjector();
// Add MVC to the request pipeline.
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
我正在开发一个网站框架,该框架使用 "Widgets" 在 portal/portlet 类型的网站内呈现内容块。基本上是 Wordpress 如何让您自定义网站的一个非常简短的版本。
经过搜索但未能找到任何现有框架,看来最合理的实现方式是使用 MVC 的 "Partial Views" 功能。
我希望能够完全封装每个 "widget" 而不必在宿主视图中重复脚本或样式标签(视图不需要知道任何有关如何呈现小部件的信息)。
为实现这一点,任何脚本引用都由 Widget Partial View 存储,然后在 View 呈现其自己的脚本部分时注入。在一个实例中,这是使用响应过滤器实现的。
我正在通过 CoreCLR 使用 MVC 6 (vNext),并且正在尝试确定如何在新框架下实现此过滤器位。似乎 HttpResponse 对象不再具有 "Filter" 字段。
你能告诉我这在新框架下如何运作吗?
/// <summary>
/// Appends partial view scripts to the html response of an AJAX request
/// </summary>
public class RenderAjaxPartialScriptsAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
var response = filterContext.HttpContext.Response;
if (response.Filter != null)
response.Filter = new RenderAjaxPartialScriptsResponseFilter(response.Filter, filterContext);
}
}
}
原始代码来自 Ryan Burnham 的博客 https://rburnham.wordpress.com/2015/03/13/asp-net-mvc-defining-scripts-in-partial-views/#comment-2286
您可以通过在 Startup.cs
中使用 Middleware
来实现:
快捷方式:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
////
app.Use(async (httpContext, next) =>
{
await next();
// if is ajax request
if (httpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
// if succesful status code
if (httpContext.Response.StatusCode == 200)
{
// you can get scripts data from httpContext.Items[key] and build html
string html = "<script src='~/js/script-demo.js'></script>";
using (var writeResponseStream = new StreamWriter(httpContext.Response.Body))
{
// write html to response body
await writeResponseStream.WriteAsync(html);
}
}
}
});
// Add MVC to the request pipeline.
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
正确的方法:
中间件实现:
public class AjaxScriptInjectorMiddleware
{
private readonly RequestDelegate _next;
public AjaxScriptInjectorMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
await _next.Invoke(context);
// if is ajax request
if (IsAjax(context.Request))
{
// if succesful status code
if (IsSuccess(context.Response.StatusCode))
{
// you can get scripts data from context.Items[key] and build html
string html = "<script src='~/js/script-demo.js'></script>";
using(var writeResponseStream = new StreamWriter(context.Response.Body))
{
// write html to response body
await writeResponseStream.WriteAsync(html);
}
}
}
}
private bool IsAjax(HttpRequest request)
{
return request.Headers["X-Requested-With"] == "XMLHttpRequest";
}
private bool IsSuccess(int statusCode)
{
return statusCode >= 200 && statusCode <= 299;
}
}
IApplicationBuilder
扩展方法:
public static class AjaxScriptInjectorExtensions
{
public static IApplicationBuilder UseAjaxScriptInjector(this IApplicationBuilder builder)
{
return builder.UseMiddleware<AjaxScriptInjectorMiddleware>();
}
}
使用middleware
:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// use custom ajax script injector middleware
app.UseAjaxScriptInjector();
// Add MVC to the request pipeline.
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}