I found some article how to return view to string in ASP.NET, but could not covert any to be able to run it with .NET Core

public static string RenderViewToString(this Controller controller, string viewName, object model)
{
    var context = controller.ControllerContext;
    if (string.IsNullOrEmpty(viewName))
        viewName = context.RouteData.GetRequiredString("action");

    var viewData = new ViewDataDictionary(model);

    using (var sw = new StringWriter())
    {
        var viewResult = ViewEngines.Engines.FindPartialView(context, viewName);
        var viewContext = new ViewContext(context, viewResult.View, viewData, new TempDataDictionary(), sw);
        viewResult.View.Render(viewContext, sw);

        return sw.GetStringBuilder().ToString();
    }
}

which assumed to be able to call from a Controller using:

var strView = this.RenderViewToString("YourViewName", yourModel);

When I try to run the above into .NET Core I get lots of compilation errors.

I tried to convert it to work with .NET Core, but failed, can anyone help with mentioning the required using .. and the required "dependencies": { "Microsoft.AspNetCore.Mvc": "1.1.0", ... }, to be used in the project.json.

some other sample codes are here and here and here

NOTE I need the solution to get the view converted to string in .NET Core, regardless same code got converted, or another way that can do it.

推荐答案

Thanks to Paris Polyzos and his article.

I'm re-posting his code here, just in case the original post got removed for any reason.

Create Service in file viewToString.cs as below code:

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Routing;
     
namespace WebApplication.Services
{
        public interface IViewRenderService
        {
            Task<string> RenderToStringAsync(string viewName, object model);
        }
     
        public class ViewRenderService : IViewRenderService
        {
            private readonly IRazorViewEngine _razorViewEngine;
            private readonly ITempDataProvider _tempDataProvider;
            private readonly IServiceProvider _serviceProvider;
     
            public ViewRenderService(IRazorViewEngine razorViewEngine,
                ITempDataProvider tempDataProvider,
                IServiceProvider serviceProvider)
            {
                _razorViewEngine = razorViewEngine;
                _tempDataProvider = tempDataProvider;
                _serviceProvider = serviceProvider;
            }
     
            public async Task<string> RenderToStringAsync(string viewName, object model)
            {
                var httpContext = new DefaultHttpContext { RequestServices = _serviceProvider };
                var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
     
                using (var sw = new StringWriter())
                {
                    var viewResult = _razorViewEngine.FindView(actionContext, viewName, false);
     
                    if (viewResult.View == null)
                    {
                        throw new ArgumentNullException($"{viewName} does not match any available view");
                    }
     
                    var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())
                    {
                        Model = model
                    };
     
                    var viewContext = new ViewContext(
                        actionContext,
                        viewResult.View,
                        viewDictionary,
                        new TempDataDictionary(actionContext.HttpContext, _tempDataProvider),
                        sw,
                        new HtmlHelperOptions()
                    );
     
                    await viewResult.View.RenderAsync(viewContext);
                    return sw.ToString();
                }
            }
        }
}

2. Add the service to the Startup.cs file, as:

using WebApplication.Services;

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddScoped<IViewRenderService, ViewRenderService>();
}

3. Add "preserveCompilationContext": true to the buildOptions in the project.json, so the file looks like:

{
    "version": "1.0.0-*",
    "buildOptions": {
    "debugType": "portable",
    "emitEntryPoint": true,
    "preserveCompilationContext": true
    },
    "dependencies": {
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.1",
    "Microsoft.AspNetCore.Mvc": "1.0.1"
    },
    "frameworks": {
    "netcoreapp1.0": {
        "dependencies": {
        "Microsoft.NETCore.App": {
            "type": "platform",
            "version": "1.0.1"
        }
        },
        "imports": "dnxcore50"
    }
    }
}

4. Define you model, for example:

public class InviteViewModel {
    public string   UserId {get; set;}
    public string   UserName {get; set;}
    public string   ReferralCode {get; set;}
    public int  Credits {get; set;}
}

5. Create your Invite.cshtml for example:

@{
    ViewData["Title"] = "Contact";
}
@ViewData["Title"].
user id: @Model.UserId

6. In the Controller:

a. Define the below at the beginning:

private readonly IViewRenderService _viewRenderService;

public RenderController(IViewRenderService viewRenderService)
{
    _viewRenderService = viewRenderService;
}

b. Call and return the view with model as below:

var result = await _viewRenderService.RenderToStringAsync("Email/Invite", viewModel);
return Content(result);

c. The FULL controller example, could be like:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using WebApplication.Services;

namespace WebApplication.Controllers
{
    [Route("render")]
    public class RenderController : Controller
    {
        private readonly IViewRenderService _viewRenderService;

        public RenderController(IViewRenderService viewRenderService)
        {
            _viewRenderService = viewRenderService;
        }

    [Route("invite")]
    public async Task<IActionResult> RenderInviteView()
    {
        ViewData["Message"] = "Your application description page.";
        var viewModel = new InviteViewModel
        {
            UserId = "cdb86aea-e3d6-4fdd-9b7f-55e12b710f78",
            UserName = "Hasan",
            ReferralCode = "55e12b710f78",
            Credits = 10
        };
     
        var result = await _viewRenderService.RenderToStringAsync("Email/Invite", viewModel);
        return Content(result);
    }

    public class InviteViewModel {
        public string   UserId {get; set;}
        public string   UserName {get; set;}
        public string   ReferralCode {get; set;}
        public int  Credits {get; set;}
    } 
}

Asp.net相关问答推荐

502 DotNet WebApplication的网关nginx已损坏

从组件属性调用异步方法的正确方法

在 lambda 表达式中否定 Func

ASP.NET MVC4 jquery/javascript 包的使用

在asp.net mvc c#中使用cookie

配置转换和TransformXml 任务失败错误消息

学习什么 - Ruby on Rails 或 ASP .NET MVC...鉴于熟悉 ASP .NET

来自 IP 地址的经度和纬度值

使用 NancyFx 的好处?

如何为角色以及特定用户使用自定义授权属性?

以编程方式添加跨度标签,而不是标签控件?

VirtualPath 在当前应用程序根目录之外

带有 2 个提交按钮/操作的 ASP.Net MVC 4 表单

通过 ASP.NET/C# 使用 Plupload

Web API 必填参数

VS 2010 中缺少 App_Code 文件夹

在 Asp.Net MVC 5 中获取登录用户的用户 ID

在控制器 asp.net-core 中获取当前区域性

Facebook 连接和 ASP.NET

如何检索 X509Store 中的所有证书