我只是寻找一个很好的方式如何从服务器返回包含部分视图的HTML和一些额外的数据,如果需要的JSON对象。部分视图作为字符串+ JsonResult
我使用approach by Tim Scott渲染partialview作为字符串(经过一些修改 - 使其成为viewenginescollection感知,使它理解视图和部分视图之间的差异,把它放到StringResult类中并用控制器扩展方法包装) 。
这里是什么原因造成的麻烦:
public static string RenderViewToString(ControllerContext controllerContext,
IView view, ViewDataDictionary viewData, TempDataDictionary tempData)
{
Stream filter = null;
ViewPage viewPage =
new ViewPage
{
ViewContext = new ViewContext
(controllerContext, view, viewData, tempData)
};
//Right, create our view
//Get the response context, flush it and get the response filter.
var response = viewPage.ViewContext.HttpContext.Response;
response.Flush();
var oldFilter = response.Filter;
try {
//Put a new filter into the response
filter = new MemoryStream();
response.Filter = filter;
//Now render the view into the memorystream and flush the response
viewPage.ViewContext.View.Render(viewPage.ViewContext, viewPage.ViewContext.HttpContext.Response.Output);
response.Flush();
//Now read the rendered view.
filter.Position = 0;
var reader = new StreamReader(filter, response.ContentEncoding);
return reader.ReadToEnd();
}
finally {
//Clean up.
if (filter != null) {
filter.Dispose();
}
//Now replace the response filter
response.Filter = oldFilter;
}
}
用法是这样的:
var v = this.ViewResultToString(PartialView("_Foo", foo));
return Json(new {Html = Server.HtmlEncode(v), Bar = foo.Bar});
但是 - 这将引发异常:
服务器无法设置内容类型之后的HTTP标头已经发出了。
这里的一个堆栈跟踪:
[HttpException(0X80004005):HTTP标头之后被发送服务器可以不设置内容类型] System.Web.HttpResponse.set_ContentType(字符串值)+ System.Web.HttpResponseWrapper.set_ContentType(String value)+11 System.Web.Mvc.JsonResult.ExecuteResult(ControllerContext context)+131 System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext,ActionResult actionResult)+10 Sys tem.Web.Mvc。 <> c__DisplayClass11.b__e()20 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter滤波器,ResultExecutingContext preContext,函数功能
1 continuation) +255 System.Web.Mvc.<>c__DisplayClass13.<InvokeActionResultWithFilters>b__10() +20 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList
1个过滤器,的ActionResult的ActionResult)179 System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)+395 System.Web.Mvc.Controller.ExecuteCore()+123 System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)+23 Company.UI.Project.Controllers.Base.BaseController.Execute( RequestContext requestContext)中的System.Web.Mvc.MvcHandler .ProcessR eQUEST的(HttpContextBase HttpContext的)144 System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext的HttpContext的)54 System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext的HttpContext的)7 的System.Web。 CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()181 System.Web.HttpApplication.ExecuteStep(IExecutionStep步骤,布尔& completedSynchronously)75
事情是 - 每当我打电话RenderViewToString,异常将如果我要返回任何不是ContentResult的其他ActionResult,就会抛出它。
所以 - 有另一种很好的方式,如何序列匿名对象转换为JSON没有第三方工具
OR
如何使这种方法的工作(如何杀了那个该死的例外,
究竟是什么迫使那些标题被发送)?
我想MVC缓存输出,所以你可能会调用Response.Clear(),甚至在内存中获取该字符串后也清除Response.Headers。 – 2009-11-17 12:15:11
@Josh也许我做错了什么 - 但它没有帮助。 – 2009-11-17 13:01:02