[英]Render an ActionResult to a String, Return it as ContentResult
[英]ActionResult to String
我知道有很多類似的問題,但是我都沒有得到想要的答案。 我想通過執行類似的操作將ActionResult轉換為String:
public ActionResult ProductDetail(int id)
{
// ... lots of operations that include usage of ViewBag and a Model ...
return View(product);
}
為了向客戶端顯示產品頁面,我還希望能夠通過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);
}
因此,我將調用 Controller Action並獲取其響應( ActionResult
,實際上是ViewResult
),然后將其轉換為String
,但是要使用controller方法的所有業務代碼(特別是ViewBag
用法)來創建它。
編輯澄清為什么我要那樣做
我需要能夠在瀏覽器中展示該產品,因此我創建了一個名為ProductDetail
Controller Action,並且運行良好。
之后,需要有一個API,該API為給定產品提供一個帶有一些元數據(如出售的單位,名稱等)和View的JSON對象。 一種選擇是發送一個到視圖的鏈接,僅此而已...但是視圖必須作為客戶需求內聯。
為了避免代碼重復並保持代碼整潔,我想調用ProductDetail
方法,並捕獲HTML Raw響應以將它作為String
放入JSON響應中。
我見過其他人使用這樣的方法渲染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();
}
}
但是這種方式不會執行控制器邏輯 。
這是一個可行的解決方案。
創建新的類:
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();
}
}
}
在您的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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.