【发布时间】:2009-11-17 12:07:03
【问题描述】:
我只是在寻找一种很好的方法,如何从服务器返回 JSON 对象,其中包含部分视图的 html 和一些额外的数据(如果需要)。
我正在使用approach by Tim Scott 将部分视图呈现为字符串(进行了一些修改 - 使其具有 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(字符串值) +8760264 System.Web.HttpResponseWrapper.set_ContentType(字符串值)+11 System.Web.Mvc.JsonResult.ExecuteResult(ControllerContext 上下文)+131 System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +10 System.Web.Mvc.c__DisplayClass11.b__e() +20 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter 过滤器,ResultExecutingContext preContext,Func
1 continuation) +255 System.Web.Mvc.<>c__DisplayClass13.<InvokeActionResultWithFilters>b__10() +20 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList1 过滤器,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) 在 c:\Project\Controllers\Base\BaseController.cs:109 System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +7 System.Web.Mvc.MvcHandler.ProcessRequest(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 step, Boolean& completedSynchronously) +75
事情是 - 每当我调用 RenderViewToString 时,如果我要返回任何其他不是 ContentResult 的 ActionResult,就会引发异常。
那么 - 还有另一种好方法如何在没有第三方工具的情况下将匿名对象序列化为 Json
OR
如何使这种方法发挥作用(如何杀死该死的异常,
究竟是什么强制发送这些标头)?
【问题讨论】:
-
我认为 MVC 会缓存输出,因此您可能会调用 Response.Clear() 甚至在将字符串放入内存后也清除 Response.Headers。
-
@Josh 也许我做错了什么 - 但它没有帮助。
标签: asp.net-mvc