为了账号安全,请及时绑定邮箱和手机立即绑定

异常将部分视图呈现为包含另一个部分视图的字符串

异常将部分视图呈现为包含另一个部分视图的字符串

C#
MMMHUHU 2021-12-05 16:56:35
我正在尝试将部分视图呈现为字符串以在 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>            }异常消息是:“RouteData 必须包含一个名为 'controller' 且具有非空字符串值的项目。”请问,我该如何解决?我知道我可以复制和粘贴第二个 Partial View 的代码,但这不是我最好的解决方案,因为我在其他地方使用了这个 Partial View,我不想重复相同的代码。
查看完整描述

1 回答

?
SMILET

TA贡献1796条经验 获得超4个赞

使用此方法将视图呈现为字符串:


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);

}


查看完整回答
反对 回复 2021-12-05
  • 1 回答
  • 0 关注
  • 158 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信