如何在ASP.NET 5中从控制器外部调用PartialView

时间:2016-01-24 18:18:58

标签: asp.net-core asp.net-core-mvc

我想创建一个可以在ASP.NET 5应用程序

中调用的公共消息框方法

代码应该是这样的:

public class WebHelper
{
    public static IActionResult MessageBox(string message)
    {
        return PartialView("~/Views/Shared/_MessageBox.cshtml", message);
    }
}

然后在我的控制器电话中:

return WebHelper.MessageBox("Hallo world");

而不是我目前正在做的事情:

 return PartialView("~/Views/Shared/_MessageBox.cshtml", "Hallo world");

然而,PartialView绑定到控制器,所以我似乎无法在控制器外使用它。

我尝试使用Answers 1 Answers 2作为ASP.NET 4的解决方案,但他们不能在ASP.NET 5中工作,例如

 public string RenderPartialViewToString(string viewName, object model)
    {
        this.ViewData.Model = model;
        try
        {
            using (StringWriter sw = new StringWriter())
            {
                ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(this.ControllerContext, viewName);
                ViewContext viewContext = new ViewContext(this.ControllerContext, viewResult.View, this.ViewData, this.TempData, sw);
                viewResult.View.Render(viewContext, sw);

                return sw.GetStringBuilder().ToString();
            }
        }
        catch (System.Exception ex)
        {
            return ex.ToString();
        }
    }

因为我无法在ViewEngines.Engine命名空间中找到ASP.NET 5

问题: 在ASP.NET 5中解决我问题的最简单方法是什么?提供方法和调用方法代码

2 个答案:

答案 0 :(得分:3)

以下是渲染视图的辅助类:(如您所见,ViewEngines.Engine部分您现在无法找到,现在注入IRazorViewEngine

using System;
using System.IO;
using Microsoft.AspNet.Http.Internal;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Abstractions;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Razor;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.ViewFeatures;
using Microsoft.AspNet.Routing;

namespace WebApp.Demo.Helpers
{
    public class RazorViewToStringRenderer
    {
        private IRazorViewEngine _viewEngine;
        private ITempDataProvider _tempDataProvider;
        private IServiceProvider _serviceProvider;

        public RazorViewToStringRenderer(
            IRazorViewEngine viewEngine,
            ITempDataProvider tempDataProvider,
            IServiceProvider serviceProvider)
        {
            _viewEngine = viewEngine;
            _tempDataProvider = tempDataProvider;
            _serviceProvider = serviceProvider;
        }

        public string RenderViewToString<TModel>(string name, TModel model)
        {
            var actionContext = GetActionContext();

            var viewEngineResult = _viewEngine.FindView(actionContext, name);

            if (!viewEngineResult.Success)
            {
                throw new InvalidOperationException(string.Format("Couldn't find view '{0}'", name));
            }

            var httpContextAccessor = new HttpContextAccessor();

            httpContextAccessor.HttpContext = actionContext.HttpContext;

            var view = viewEngineResult.View;

            using (var output = new StringWriter())
            {
                var viewContext = new ViewContext(
                    actionContext,
                    view,
                    new ViewDataDictionary<TModel>(
                        metadataProvider: new EmptyModelMetadataProvider(),
                        modelState: new ModelStateDictionary())
                    {
                        Model = model
                    },
                    new TempDataDictionary(
                        httpContextAccessor,
                        _tempDataProvider),
                    output,
                    new HtmlHelperOptions());

                view.RenderAsync(viewContext).GetAwaiter().GetResult();

                return output.ToString();
            }
        }

        private ActionContext GetActionContext()
        {
            var httpContext = new DefaultHttpContext();
            httpContext.RequestServices = _serviceProvider;
            return new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
        }
    }
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
       // Add MVC services to the services container.
       services.AddMvc();
       // Add the helper rendering class as singleton
       services.AddSingleton<RazorViewToStringRenderer>();
}

在控制器中获取注入的辅助类,例如:

public HomeController(RazorViewToStringRenderer renderer)
{
       string message = "Hallo world";

       var partialView = renderer.RenderViewToString("~/Views/Shared/_MessageBox.cshtml", message);
}

此处的代码,只需进行一些调整即可使用"Microsoft.AspNet.Mvc": "6.0.0-rc1-final"之类的旧软件包:https://github.com/aspnet/Entropy/tree/dev/samples/Mvc.RenderViewToString

如果您使用新的"Microsoft.AspNetCore.Mvc": "1.0.0-*",只需从中获取代码

答案 1 :(得分:1)

聚会晚了一点,但是我遇到了同样的问题,以前的答案和评论中的链接现在似乎断开了。

我用来解决此问题的解决方案是创建一个继承自“ Controller”的抽象类。

    public abstract class MyControllerBase : Controller
    {
        protected IActionResult MessageBox(string message)
        {
            return PartialView("~/Views/Shared/_MessageBox.cshtml", message);
        }
    {

只需确保您的控制器继承自该基类,然后在您的控制器中只需要:

return MessageBox("Hello world");