Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在ASP.NET核心中将Razor视图呈现为字符串_C#_Razor_Asp.net Core_Asp.net Core Mvc - Fatal编程技术网

C# 在ASP.NET核心中将Razor视图呈现为字符串

C# 在ASP.NET核心中将Razor视图呈现为字符串,c#,razor,asp.net-core,asp.net-core-mvc,C#,Razor,Asp.net Core,Asp.net Core Mvc,我在MVC 6项目中使用以下方法解析模板: Engine.Razor.RunCompile(File.ReadAllText(fullTemplateFilePath), templateName, null, model); 它适用于beta 6。升级到beta 7后无法工作,错误为: MissingMethodException:找不到方法:“Void Microsoft.AspNet.Razor.CodeGenerators.GeneratedClassContext.set_Resol

我在MVC 6项目中使用以下方法解析模板:

Engine.Razor.RunCompile(File.ReadAllText(fullTemplateFilePath), templateName, null, model);
它适用于beta 6。升级到beta 7后无法工作,错误为:

MissingMethodException:找不到方法:“Void Microsoft.AspNet.Razor.CodeGenerators.GeneratedClassContext.set_ResolveUrlMethodName(System.String)”。 在RazorEngine.Compilation.CompilerServiceBase.CreateHost中(类型templateType、类型modelType、字符串className)

这是global.json:

{
  "projects": [ "src", "test" ],
  "sdk": {
    "version": "1.0.0-beta7",
    "runtime": "clr",
    "architecture": "x64"
  }
}
这是project.json:

...
"dependencies": {
    "EntityFramework.SqlServer": "7.0.0-beta7",
    "EntityFramework.Commands": "7.0.0-beta7",
    "Microsoft.AspNet.Mvc": "6.0.0-beta7",
    "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-beta7",
    "Microsoft.AspNet.Authentication.Cookies": "1.0.0-beta7",
    "Microsoft.AspNet.Authentication.Facebook": "1.0.0-beta7",
    "Microsoft.AspNet.Authentication.Google": "1.0.0-beta7",
    "Microsoft.AspNet.Authentication.MicrosoftAccount": "1.0.0-beta7",
    "Microsoft.AspNet.Authentication.Twitter": "1.0.0-beta7",
    "Microsoft.AspNet.Diagnostics": "1.0.0-beta7",
    "Microsoft.AspNet.Diagnostics.Entity": "7.0.0-beta7",
    "Microsoft.AspNet.Identity.EntityFramework": "3.0.0-beta7",
    "Microsoft.AspNet.Server.IIS": "1.0.0-beta7",
    "Microsoft.AspNet.Server.WebListener": "1.0.0-beta7",
    "Microsoft.AspNet.StaticFiles": "1.0.0-beta7",
    "Microsoft.AspNet.Tooling.Razor": "1.0.0-beta7",
    "Microsoft.Framework.Configuration.Abstractions": "1.0.0-beta7",
    "Microsoft.Framework.Configuration.Json": "1.0.0-beta7",
    "Microsoft.Framework.Configuration.UserSecrets": "1.0.0-beta7",
    "Microsoft.Framework.Logging": "1.0.0-beta7",
    "Microsoft.Framework.Logging.Console": "1.0.0-beta7",
    "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-beta7",
    "RazorEngine": "4.2.2-beta1"
  },
...
  "frameworks": {
    "dnx451": { }
  },
...
我的模板是:

@模型动态
@{
布局=空;
}
登记处

你好,@Model


已删除ResolveUrlMethodName
。因此,在
CreateHost
中,您试图设置一个不存在的属性:)

我们决定将
~/
处理从core Razor移动到
TagHelper
中,并在
Microsoft.AspNet.Mvc.Razor
程序集中实现。以下是删除该方法的位的示例


希望这会有所帮助。

过去,我在类库中使用了
RazorEngine
,因为我的目标是从类库中呈现模板

据我所知,您似乎在一个MVC 6.0项目中,所以为什么不使用
RenderPartialViewToString()
方法,而不必添加对
RazorEngine
的依赖性呢

记住,我只是出于好奇才这么问的

例如,在VS2015中,我创建了一个新的ASP.NET Web应用程序,并从ASP.NET 5预览模板中选择了Web应用程序模板

ViewModels
文件夹中,我创建了一个
PersonViewModel

公共类PersonViewModel
{
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共字符串全名
{
得到
{
返回string.Format(“{0}{1}”,this.FirstName,this.LastName);
}
} 
}
然后,我创建了一个新的
BaseController
,并添加了一个
RenderPartialViewToString()
方法:

public string RenderPartialViewToString(字符串视图名,对象模型)
{
if(string.IsNullOrEmpty(viewName))
viewName=ActionContext.ActionDescriptor.Name;
ViewData.Model=Model;
使用(StringWriter sw=new StringWriter())
{
var engine=Resolver.GetService(typeof(ICompositeViewEngine))作为ICompositeViewEngine;
ViewEngineResult viewResult=engine.FindPartialView(ActionContext,viewName);
ViewContext ViewContext=新的ViewContext(ActionContext、viewResult.View、ViewData、TempData、sw、新的HTMLHelpOptions());
var t=viewResult.View.RenderAsync(viewContext);
t、 等待();
返回sw.GetStringBuilder().ToString();
}
}
大卫的成功归功于他

Views-->Shared
文件夹中,我创建了一个新的Templates文件夹,在其中我向我的
PersonViewModel
添加了一个简单的
RegistrationTemplate.cshtml
View强类型的,如下所示:

@model MyWebProject.ViewModels.PersonViewModel
登记处

您好,@Model.FullName

最后一步是使我的
控制器
继承自我的
基本控制器

公共类MyController:BaseController
并创建如下内容:

public IActionResult Index()
{
var模型=新PersonViewModel();
model.FirstName=“Frank”;
model.LastName=“安德伍德”;
var emailbody=base.RenderPartialViewToString(“模板/注册模板”,模型);
返回视图();
}
当然,上面的示例是无用的,因为我对变量
emailbody
不做任何处理,但其目的是展示如何使用它

此时,我可以(例如)调用
EmailService
并传递
emailbody

\u emailService.SendEmailAsync(“test@test.com“,”注册“,电子邮件正文);
我不确定这是否适合您当前的任务。

2016年7月更新 在以下版本
1.0.0
RC2


谁的目标是aspnetcore RC2,此片段可能会帮助您:

  • 创建一个单独的服务,这样,如果您不在控制器上下文中(例如,从命令行或队列运行程序等),您就可以使用它
  • 启动
    类中的IoC容器中注册此服务

用法
//使用模型
字符串html=view.Render(“电子邮件/测试”,新产品(“苹果”);
//使用字典
var viewData=新字典();
viewData[“名称”]=“123456”;
字符串html=view.Render(“电子邮件/测试”,viewData);
笔记 Razor中的链接呈现为相对URL,因此这在外部视图(如电子邮件等)上不起作用

现在,我正在控制器上生成链接,并通过ViewModel将其传递给视图

信用
源代码是从中提取的(感谢@pholly):)

今天我已经完成了我的库,它可以解决您的问题。您可以在ASP.NET之外使用它,因为它对它没有依赖关系

例如:

string content = "Hello @Model.Name. Welcome to @Model.Title repository";

var model = new
{
  Name = "John Doe",
  Title = "RazorLight"
};

var engine = new RazorLightEngine();
string result = engine.ParseString(content, model);

//Output: Hello John Doe, Welcome to RazorLight repository

更多信息:

为了改进@vlince答案(这对我来说不是现成的),以下是我所做的:

1-创建其他控制器将继承的基本控制器

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.IO;

namespace YourNameSpace
{
    public class BaseController : Controller
    {
        protected ICompositeViewEngine viewEngine;

        public BaseController(ICompositeViewEngine viewEngine)
        {
            this.viewEngine = viewEngine;
        }

        protected string RenderViewAsString(object model, string viewName = null)
        {
            viewName = viewName ?? ControllerContext.ActionDescriptor.ActionName;
            ViewData.Model = model;

            using (StringWriter sw = new StringWriter())
            {
                IView view = viewEngine.FindView(ControllerContext, viewName, true).View;
                ViewContext viewContext = new ViewContext(ControllerContext, view, ViewData, TempData, sw, new HtmlHelperOptions());

                view.RenderAsync(viewContext).Wait();

                return sw.GetStringBuilder().ToString();
            }
        }
    }
}
2-继承基本控制器并调用方法

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewEngines;

namespace YourNameSpace
{
    public class YourController : BaseController
    {
        public YourController(ICompositeViewEngine viewEngine) : base(viewEngine) { }

        public string Index(int? id)
        {
            var model = new MyModel { Name = "My Name" };

            return RenderViewAsString(model);
        }
    }
}

我找到了这个讨论它的帖子:

线程中的某个人在此处创建了一个示例服务:

经过反复试验之后,我能够精简服务,这样它只需要一个有效的
HttpContext
和一个
ViewEngine
,并且我添加了一个不需要模型的重载。视图是相对于应用程序根目录的(它们不必位于
Views
文件夹中)

您需要注册s
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewEngines;

namespace YourNameSpace
{
    public class YourController : BaseController
    {
        public YourController(ICompositeViewEngine viewEngine) : base(viewEngine) { }

        public string Index(int? id)
        {
            var model = new MyModel { Name = "My Name" };

            return RenderViewAsString(model);
        }
    }
}
public static class PartialViewToString
{
    public static async Task<string> ToString(this PartialViewResult partialView, ActionContext actionContext)
    {
        using(var writer = new StringWriter())
        {
            var services = actionContext.HttpContext.RequestServices;
            var executor = services.GetRequiredService<PartialViewResultExecutor>();
            var view = executor.FindView(actionContext, partialView).View;
            var viewContext = new ViewContext(actionContext, view, partialView.ViewData, partialView.TempData, writer, new HtmlHelperOptions());
            await view.RenderAsync(viewContext);
            return writer.ToString();
        }
    }
}
public async Task<IActionResult> Index()
{
    return await PartialView().ToString(ControllerContext)
}
public static async Task<string> ViewToString(this PartialViewResult partialView, Controller controller)
    {
        using (var writer = new StringWriter())
        {
            var services = controller.ControllerContext.HttpContext.RequestServices;
            var viewEngine = services.GetService(typeof(ICompositeViewEngine)) as ICompositeViewEngine;
            var viewName = partialView.ViewName ?? controller.ControllerContext.ActionDescriptor.ActionName;
            var view = viewEngine.FindView(controller.ControllerContext, viewName, false).View;
            var viewContext = new ViewContext(controller.ControllerContext, view, partialView.ViewData, partialView.TempData, writer, new HtmlHelperOptions());
            await view.RenderAsync(viewContext);
            return writer.ToString();
        }
    }