gpt4 book ai didi

c# - 将 ActionResult 呈现为字符串 - 输出顺序不正确

转载 作者:行者123 更新时间:2023-11-30 16:19:32 24 4
gpt4 key购买 nike

我有一个尝试将 ActionResult 呈现为字符串的解决方案。我通过传入我自己的 HttpContext 来实现这一点,它将输出文本编写器替换为我自己的 TextWriter

这就是问题所在 - 元素呈现无序。如果我通过直接通过浏览器查询来呈现部分 View ,它工作正常。如果我通过替代的文本编写器呈现它,razor View 中的任何 @Html.Action 元素都会首先呈现,无论它们在 View 中的位置如何。

所以,这是我的 Razor View :

@inherits System.Web.Mvc.WebViewPage<WebsitePresentationLayer.MgrScreenLayoutViewer>
@using System.Web.Mvc.Html;

<div>
@Model.DebugText
</div>
@foreach (var item in @Model.Items)
{
<div>@item.Title</div>
@Html.Action(
"LayoutItem",
new
{
id = item.Id,
uniqueName = item.UniqueName
}
);

}

如果我直接通过浏览器查询 View ,它会以正确的顺序呈现:

  • @Model.DebugText
  • Item1.Title
  • Item1 Action 渲染
  • Item2.Title
  • Item2 Action 渲染

如果我将其呈现给我的 TextWriter,它会按以下顺序呈现:

  • Item1 Action 渲染
  • Item2 Action 渲染
  • @Model.DebugText
  • Item1.Title
  • Item2.Title

为什么?

以下是我如何替换文本编写器。 (我是从 ASP.NET WebForms 页面调用它的,所以已经有一个现有的 HttpContext)

public static class ActionResultExtensions
{
internal class MyResponseWrapper : HttpResponseWrapper
{
private System.IO.TextWriter _textWriter;
public MyResponseWrapper(HttpResponse wrappedResponse, System.IO.TextWriter textWriter)
: base(wrappedResponse)
{
_textWriter = textWriter;
}

public override System.IO.TextWriter Output
{
get { return this._textWriter; }
set { this._textWriter = value; }
}
}

internal class MyHttpContextWrapper : HttpContextWrapper
{
private readonly System.IO.TextWriter _textWriter;
public MyHttpContextWrapper(System.IO.TextWriter textWriter)
: base(HttpContext.Current)
{
this._textWriter = textWriter;
}

public override HttpResponseBase Response
{
get
{
var httpResponse = HttpContext.Current.Response;
return new MyResponseWrapper(httpResponse, this._textWriter);
}
}
}


public static void Render(this System.Web.Mvc.ActionResult result, System.IO.TextWriter textWriter, System.Web.Routing.RouteData routeData, System.Web.Mvc.ControllerBase controllerBase)
{
var httpContextWrapper = new MyHttpContextWrapper(textWriter);
result.ExecuteResult(new System.Web.Mvc.ControllerContext(httpContextWrapper, routeData, controllerBase));
}
}

public static class MvcUtils
{
public static void RenderControllerAction<T>(Func<T, System.Web.Mvc.ActionResult> f, System.IO.TextWriter writer) where T : System.Web.Mvc.ControllerBase, new()
{
var controller = new T();
// We have to initialise the RouteData so that it knows the name of the controller
// This is used to locate the view
var typeName = controller.GetType().Name;
System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex("(.*)Controller$");
var match = regex.Match(typeName);
if (match.Success)
{
typeName = match.Groups[1].Value;
}
var routeData = new System.Web.Routing.RouteData();
routeData.Values.Add("controller", typeName);

var actionResult = f(controller);
actionResult.Render(writer, routeData, controller);
}
}

然后我最终使用以下代码将其输出为字符串:

StringBuilder sb = new StringBuilder();
StringWriter stringWriter = new StringWriter(sb);

CMS.Website.MvcUtils.RenderControllerAction<PlayerGroupController>
(
c => c.ScreenLayout(this.MgrPlayerGroupViewer.ScreenLayoutId),
stringWriter
);
stringWriter.Flush();
var generatedString = sb.ToString();


我已经为 TextWriter 编写了一个拦截器,果然,它收到了三个对 Write(string)

的调用
  • 写(LayoutItem 1 Action 内容)
  • 写(LayoutItem 2 Action 内容)
  • 写(Model.DebugText 和两个项目标题)

最佳答案

我大约 6 个月前经历过这个。目标是使用部分来填充 jquery 弹出对话框。

问题是 View 引擎想要按照它自己的尴尬顺序呈现它们...

试试这个。 LMK 如果需要澄清。

    public static string RenderPartialViewToString(Controller thisController, string viewName, object model)
{
// assign the model of the controller from which this method was called to the instance of the passed controller (a new instance, by the way)
thisController.ViewData.Model = model;

// initialize a string builder
using (StringWriter sw = new StringWriter())
{
// find and load the view or partial view, pass it through the controller factory
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(thisController.ControllerContext, viewName);
ViewContext viewContext = new ViewContext(thisController.ControllerContext, viewResult.View, thisController.ViewData, thisController.TempData, sw);

// render it
viewResult.View.Render(viewContext, sw);

//return the razorized view/partial-view as a string
return sw.ToString();
}
}

关于c# - 将 ActionResult 呈现为字符串 - 输出顺序不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15236146/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com