Vic*_*scó 2 c# asp.net asp.net-mvc view
我知道有很多类似的问题,但我没有得到任何我想要的答案.我希望通过执行类似的操作将ActionResult转换为String:
public ActionResult ProductDetail(int id)
{
// ... lots of operations that include usage of ViewBag and a Model ...
return View(product);
}
Run Code Online (Sandbox Code Playgroud)
要向客户端显示产品页面,我希望能够通过JSON发送它,例如:
public JsonResult ProductDetailJSON(int id)
{
// ... lots of operations that include usage of ViewBag and a Model ...
return Json(new {
html = this.ProductDetail(id).ToString(),
name = ""
// ... more properties
}, JsonRequestBehavior.AllowGet);
}
Run Code Online (Sandbox Code Playgroud)
因此,我将调用 Controller Action并获取其响应(a ActionResult,实际上是a ViewResult)并将其转换为a String,但是使用控制器方法的所有业务代码(包括,特别是ViewBag用法)创建它.
编辑澄清为什么我想这样做
我需要能够在浏览器中显示产品,因此我创建了一个名为的Controller Action ProductDetail,并且工作得很好.
在此之后需要一个API,为给定的产品提供一个带有一些元数据(如销售单位,名称等)和View的JSON对象.一种选择是发送一个链接到视图,这就是全部...但视图必须作为客户端要求内联.
为了避免代码重复并保持代码清洁,我想调用该方法ProductDetail,并捕获HTML Raw响应以将其作为一个内容放入JSON响应中String.
我见过其他人用这样的方法渲染View:
public string RenderRazorViewToString(string viewName, object model)
{
ViewData.Model = model;
using (var sw = new StringWriter())
{
var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
return sw.GetStringBuilder().ToString();
}
}
Run Code Online (Sandbox Code Playgroud)
但这种方式不会执行控制器逻辑.
这是一个有效的解决方案.
创建新类:
public class ResponseCapture : IDisposable
{
private readonly HttpResponseBase response;
private readonly TextWriter originalWriter;
private StringWriter localWriter;
public ResponseCapture(HttpResponseBase response)
{
this.response = response;
originalWriter = response.Output;
localWriter = new StringWriter();
response.Output = localWriter;
}
public override string ToString()
{
localWriter.Flush();
return localWriter.ToString();
}
public void Dispose()
{
if (localWriter != null)
{
localWriter.Dispose();
localWriter = null;
response.Output = originalWriter;
}
}
}
public static class ActionResultExtensions
{
public static string Capture(this ActionResult result, ControllerContext controllerContext)
{
using (var it = new ResponseCapture(controllerContext.RequestContext.HttpContext.Response))
{
result.ExecuteResult(controllerContext);
return it.ToString();
}
}
}
Run Code Online (Sandbox Code Playgroud)
在你的json方法中这样做:
public JsonResult ProductDetailJSON(int id)
{
// ... lots of operations that include usage of ViewBag and a Model ...
return Json(new {
// ControllerContext - modify it so it accepts Id
html = View("ProductDetail").Capture(ControllerContext),
name = ""
// ... more properties
}, JsonRequestBehavior.AllowGet);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8184 次 |
| 最近记录: |