0

在 MVC 项目中,我使用以下代码将视图动态呈现为字符串。

public string RenderViewToString(string viewName, object model, RequestContext requestContext){
            ViewData.Model = model;
            var cContext = ControllerContext;
            if (cContext == null)
            {
                var ctrlFactory = ControllerBuilder.Current.GetControllerFactory();
                var ctrl = ctrlFactory.CreateController(requestContext, "Documents") as Controller;
                var newCContext = new ControllerContext(requestContext, ctrl);
                cContext = newCContext;
                var ctrlDesc = new ReflectedControllerDescriptor(ctrl.GetType());
            }
            using (var sw = new StringWriter())
            {
                var viewResult = ViewEngines.Engines.FindPartialView(cContext, viewName);
                var viewContext = new ViewContext(cContext, viewResult.View, ViewData, TempData, sw);
                viewResult.View.Render(viewContext, sw);
                viewResult.ViewEngine.ReleaseView(cContext, viewResult.View);
                return sw.GetStringBuilder().ToString();
            }
        }

这工作正常,直到多个用户同时运行代码。然后它将每个用户的视图数据混合在一起。

任何建议为什么?谢谢

4

1 回答 1

0

我对类似的代码有同样的问题。我花了几天时间弄清楚这个。在阅读了这方面的负载后,包含诸如“编写你自己的 viewRenderer”之类的建议,解决这个问题似乎很复杂。在深入研究 .net 代码本身之后,我发现了一个可以解决此问题的肮脏技巧

在您的 ConfigureServices(启动)中添加几行:

  services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
  services.AddTransient<IViewRenderer, ViewRenderer>();

  // reason for this registration https://github.com/aspnet/Mvc/issues/5106 . A scoped buffer causes overflow.
  var memoryPoolViewBufferScopeType = Type.GetType("Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers.MemoryPoolViewBufferScope, Microsoft.AspNetCore.Mvc.ViewFeatures");
  if (memoryPoolViewBufferScopeType != null)
  {
    services.AddTransient(typeof(IViewBufferScope), memoryPoolViewBufferScopeType);
  }

它使 IViewRenderer 和 IViewBufferScope 瞬态,从而解决了问题。以这种方式添加 IViewBufferScope 的原因是因为它是内部的,因此需要一些技巧来获得它。

于 2021-03-20T21:45:19.320 回答