c# - 异常将局部视图呈现为包含另一个局部视图的字符串
问题描述
我正在尝试将部分视图呈现为字符串以在 JSON 对象中返回。我有这个代码来做到这一点:
/// <summary>
/// Render razor view to a string.
/// </summary>
/// <param name="model">Model sent to view.</param>
/// <param name="filePath">Path to the view location in project hierarchy.</param>
/// <returns>String with the html code of returned view.</returns>
public static string Func_GetRazorViewAsString(object model, string filePath)
{
var st = new StringWriter();
var context = new HttpContextWrapper(HttpContext.Current);
var routeData = new RouteData();
var controllerContext = new ControllerContext(new RequestContext(context, routeData), new FakeController());
var razor = new RazorView(controllerContext, filePath, null, false, null);
razor.Render(new ViewContext(controllerContext, razor, new ViewDataDictionary(model), new TempDataDictionary(), st), st);
return st.ToString();
}
当 View 不包含 PartialView 时它工作得很好,但是当要渲染的视图调用另一个 Partial View 时它会抛出异常。例如:
@using Anpr_Web_Manager.App_GlobalResources
@model IEnumerable<Anpr_Web_Manager.Models.DetectionCardViewModel>
@{
int iCountElementsRow = 0;
int iNumberElements = Model.Count();
int iNumNavigationPages = (int)Math.Ceiling(iNumberElements / (double)3);
}
<div class="col-12 bootstrap-carousel">
<div id="carouselDetections" class="carousel slide" data-ride="carousel" data-interval="false">
@if (iNumberElements != 0)
{
@:<ol class="carousel-indicators">
<li data-target="#carouselDetections" data-slide-to="0" class="active"></li>
for (int i = 1; i < iNumNavigationPages; i++)
{
<li data-target="#carouselDetections" data-slide-to="@i"></li>
}
@:</ol>
}
<div class="container carousel-inner">
<div class="row row-equal row-slider carousel-item active">
@foreach (var item in Model)
{
if (iCountElementsRow != 0 && iCountElementsRow % 3 == 0)
{
//Insert new row
@:</div>
@:<div class="row row-equal row-slider carousel-item">
}
//TODO: RENDER ELEMENT
@Html.Partial("~/Views/Capturas/_DetectionElement.cshtml", item);
iCountElementsRow++;
}
</div>
</div>
</div>
</div>
异常消息是:
“RouteData 必须包含一个名为 'controller' 且具有非空字符串值的项目。”
请问,我该如何解决?我知道我可以复制和粘贴第二个局部视图的代码,但这不是我最好的解决方案,因为我在其他地方使用这个局部视图,我不想重复相同的代码。
非常感谢。此致,
解决方案
使用此方法将视图呈现为字符串:
public static string RenderViewToString(ControllerContext context, string viewPath, object viewModel = null, bool partial = false)
{
// get the ViewEngine for this view
ViewEngineResult viewEngineResult = null;
if (partial)
viewEngineResult = ViewEngines.Engines.FindPartialView(context, viewPath);
else
viewEngineResult = ViewEngines.Engines.FindView(context, viewPath, null);
if (viewEngineResult == null)
throw new FileNotFoundException("View cannot be found.");
// get the view and attach the model to view data
var view = viewEngineResult.View;
context.Controller.ViewData.Model = viewModel;
string result = null;
using (var sw = new StringWriter())
{
var ctx = new ViewContext(context, view, context.Controller.ViewData, context.Controller.TempData, sw);
view.Render(ctx, sw);
result = sw.ToString();
}
return result;
}
如果您致电:
@foreach (var item in Model.SomeIEnumerableModel)
{
@Html.Partial("~/Views/SomePath/SomeViewTwo.cshtml", item);
}
在“父部分视图”中。
可以使用它在控制器中调用它(假设您从 ajax 请求返回 json,并且该RenderViewToString
方法位于调用控制器中):
public ActionResult TestViewToString()
{
var viewModel = new TestViewModel();
// Populate ViewModel here ...
string data = RenderViewToString(ControllerContext, "~/Views/SomePath/SomeViewOne.cshtml", viewModel, true);
return Json(data, JsonRequestBehavior.AllowGet);
}
推荐阅读
- python-3.x - 保存方法无法按预期在 Django 中工作
- docker - 如何解决来自 docker daemon 的错误响应 - $PATH 中找不到可执行文件:未知
- visual-studio-code - `contributes.commands` 中的 `shortTitle` 有什么作用?
- docker - 如何解决 docker-compose 文件中的端口问题
- swift - 我应该避免在 Swift 中使用常量文件夹吗
- python - Python无限递归与数字
- javascript - 灯箱 Cushycms
- apache-kafka - 在 k8s 上使用 Strimzi 部署远程调试自定义 Kafka 连接器
- xml - 如何再次准确设置moveTo?
- ansible - Ansible - 如何解决 - 权限被拒绝 - 使用 lineinfile 模块时