问题
i am using Orchard 1.6 and want to render view to string with theme custom layout and so on.
In fact there is orchard cms rendering shape as email template but i need some more details (cant add comment to that answer, i dont have rep enough :(, and cant send private message)
I do it in controller for test (in future i want to do int in separate task). So controller is (model is simple class with some properties)
var renderer = new ViewRenderer(
_workContextAccessor,
_siteThemeService,
_services);
var shape = ShapeFactory.MyTestShape(Model: model);
var result = renderer.RenderMessage(shape);
renderer is
public string RenderMessage(dynamic shape)
{
var httpContext = new ViewRendererHttpContext(new Uri("http://localhost/orchard/"));
var routeData = new RouteData();
routeData.DataTokens.Add("IWorkContextAccessor", _workContextAccessor);
routeData.Values["controller"] = "Dummy";
var requestContext = new RequestContext(httpContext, routeData);
var controllerContext = new ControllerContext(requestContext, new DummyController());
var viewContext = new ViewContext(controllerContext, new ShapeView(shape), new ViewDataDictionary(shape.Model), new TempDataDictionary(), new StringWriter());
var scope = _workContextAccessor.CreateWorkContextScope(viewContext.HttpContext);
scope.WorkContext.CurrentTheme = _siteThemeService.GetSiteTheme();
var page = new ViewRendererWebViewPage(viewContext, new ViewDataDictionary<dynamic>(shape.Model));
var displayHelperFactory = _services.WorkContext.Resolve<IDisplayHelperFactory>();
var display = displayHelperFactory.CreateHelper(page.ViewContext, page);
var data = display(shape).ToHtmlString();
scope.Dispose();
return data;
}
ViewRendererHttpContext just derived from HttpContextBase and very simple (can post its code), DummyController is empty class derived from Controller, ShapeView is epmty class derived from IView.
Ofc i have View/MyTestShape.cshtml in my module.
Problem is when executing var data = display(shape).ToHtmlString();
in depth
var result = htmlHelper.Partial(harvestShapeInfo.TemplateVirtualPath, displayContext.Value);
(class "ShapeTemplateBindingStrategy",
method "private IHtmlString Render(......)")
I have exception "The method or operation is not implemented."
What method and in what class i should implement?
Thanks for any tips. My english is very bad so sorry for it.
回答1:
It does not work with me either, I am using Orchard 1.6. There used to be a vote to make it work but I am not sure it is taken in Orchard 1.7.
Here is my way to do it in my project (I render shapes to string for ajax DataTables), provided that you make the call from a controller.
Inside your service (or controller), get your hand to 2 services: IThemeAwareViewEngine and IDisplayHelperFactory:
private readonly IThemeAwareViewEngine _themeAwareViewEngine;
private readonly IDisplayHelperFactory _displayHelperFactory;
public AjaxDataTables(
IThemeAwareViewEngine themeAwareViewEngine,
IDisplayHelperFactory displayHelperFactory
)
{
_themeAwareViewEngine = themeAwareViewEngine;
_displayHelperFactory = displayHelperFactory;
}
Here is the way to get the magic display, provided that you have a reference to a real controller:
dynamic GetDisplayHelper(Controller controller)
{
// We can specify any view name, just to get a View only, the shape template finding will be taken care by DisplayHelperFactory.
// Here the "Brandking" view is always existed, we can also use something like "Layout" ...
var viewResult = _themeAwareViewEngine.FindPartialView(controller.ControllerContext, "Branding", false, false);
var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, new StringWriter());
return _displayHelperFactory.CreateHelper(viewContext, new ViewDataContainer());
}
private class ViewDataContainer : IViewDataContainer
{
public ViewDataDictionary ViewData { get; set; }
}
And render shape to string:
var display = GetDisplayHelper(controller);
var str = Convert.ToString(display(shape.Content));
Again, this work only if you make call from a controller action.
HTH, Huy
来源:https://stackoverflow.com/questions/16951605/how-to-render-shape-to-string