Asp.net core 使用mailkit发送cshtml查看邮件

Asp.net core 使用mailkit发送cshtml查看邮件,asp.net-core,mailkit,Asp.net Core,Mailkit,我正在使用ASP.NET内核和Mailkit发送电子邮件。以以下(基本)代码为例: GetBody()方法只读取html文档(streamreader) 我想做的是使用razor视图和cshtml,因为我的电子邮件可能包含动态内容(例如,某些项目的未知大小的集合) 我似乎找不到关于如何做到这一点的明确文档。这样做的目的是将cshtml视图作为普通html读取,但解析razor语法和模型变量 有人这样做过吗?一种解决方案是从您的控制器传递内容 public void TestAction(){

我正在使用ASP.NET内核和Mailkit发送电子邮件。以以下(基本)代码为例:

GetBody()方法只读取html文档(streamreader)

我想做的是使用razor视图和cshtml,因为我的电子邮件可能包含动态内容(例如,某些项目的未知大小的集合)

我似乎找不到关于如何做到这一点的明确文档。这样做的目的是将cshtml视图作为普通html读取,但解析razor语法和模型变量


有人这样做过吗?

一种解决方案是从您的控制器传递内容

public void TestAction(){
     var content = PartialView("your_partial_view").ToString();
     your_SendEmailFunction(content)
}

因此,基本上您使用部分视图作为字符串,并将其作为内容传递给方法

下面是一个基于以下内容的简单演示:

1.自定义界面:

public interface IViewRenderService
{
    Task<string> RenderToStringAsync(string viewName, object model);
}
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;

public class ViewRenderService : IViewRenderService
{
    private readonly IRazorViewEngine _razorViewEngine;
    private readonly ITempDataProvider _tempDataProvider;
    private readonly HttpContext _httpContext;


    public ViewRenderService(IRazorViewEngine razorViewEngine,
        ITempDataProvider tempDataProvider,
        IHttpContextAccessor httpContextAccessor)
    {
        _razorViewEngine = razorViewEngine;
        _tempDataProvider = tempDataProvider;
        _httpContext = httpContextAccessor.HttpContext;
    }


    public async Task<string> RenderToStringAsync(string viewName, object model)
    {

        var actionContext = new ActionContext(_httpContext, new RouteData(), new ActionDescriptor());
        var viewEngineResult = _razorViewEngine.FindView(actionContext, viewName, false);

        if (viewEngineResult.View == null || (!viewEngineResult.Success))
        {
            throw new ArgumentNullException($"Unable to find view '{viewName}'");
        }

        var view = viewEngineResult.View;


        using (var sw = new StringWriter())
        {
            var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary());
            viewDictionary.Model = model;

            var tempData = new TempDataDictionary(_httpContext, _tempDataProvider);

            var viewContext = new ViewContext(actionContext, view, viewDictionary, tempData, sw, new HtmlHelperOptions());

            viewContext.RouteData = _httpContext.GetRouteData();   //set route data here

            await view.RenderAsync(viewContext);

            return sw.ToString();
        }
    }

}
公共接口IViewRenderService
{
任务RenderToStringAsync(字符串视图名称、对象模型);
}
2.实现接口:

public interface IViewRenderService
{
    Task<string> RenderToStringAsync(string viewName, object model);
}
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;

public class ViewRenderService : IViewRenderService
{
    private readonly IRazorViewEngine _razorViewEngine;
    private readonly ITempDataProvider _tempDataProvider;
    private readonly HttpContext _httpContext;


    public ViewRenderService(IRazorViewEngine razorViewEngine,
        ITempDataProvider tempDataProvider,
        IHttpContextAccessor httpContextAccessor)
    {
        _razorViewEngine = razorViewEngine;
        _tempDataProvider = tempDataProvider;
        _httpContext = httpContextAccessor.HttpContext;
    }


    public async Task<string> RenderToStringAsync(string viewName, object model)
    {

        var actionContext = new ActionContext(_httpContext, new RouteData(), new ActionDescriptor());
        var viewEngineResult = _razorViewEngine.FindView(actionContext, viewName, false);

        if (viewEngineResult.View == null || (!viewEngineResult.Success))
        {
            throw new ArgumentNullException($"Unable to find view '{viewName}'");
        }

        var view = viewEngineResult.View;


        using (var sw = new StringWriter())
        {
            var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary());
            viewDictionary.Model = model;

            var tempData = new TempDataDictionary(_httpContext, _tempDataProvider);

            var viewContext = new ViewContext(actionContext, view, viewDictionary, tempData, sw, new HtmlHelperOptions());

            viewContext.RouteData = _httpContext.GetRouteData();   //set route data here

            await view.RenderAsync(viewContext);

            return sw.ToString();
        }
    }

}
使用系统;
使用System.IO;
使用System.Threading.Tasks;
使用Microsoft.AspNetCore.Http;
使用Microsoft.AspNetCore.Mvc;
使用Microsoft.AspNetCore.Mvc.Abstractions;
使用Microsoft.AspNetCore.Mvc.ModelBinding;
使用Microsoft.AspNetCore.Mvc.Razor;
使用Microsoft.AspNetCore.Mvc.Rendering;
使用Microsoft.AspNetCore.Mvc.ViewFeatures;
使用Microsoft.AspNetCore.Routing;
公共类ViewRenderService:IViewRenderService
{
私有只读IRazorViewEngine(U razorViewEngine);
私有只读ITempDataProvider _tempDataProvider;
私有只读HttpContext\u HttpContext;
公共视图渲染服务(IRazorViewEngine razorViewEngine,
ITempDataProvider tempDataProvider,
IHttpContextAccessor(httpContextAccessor)
{
_razorViewEngine=razorViewEngine;
_tempDataProvider=tempDataProvider;
_httpContext=httpContextAccessor.httpContext;
}
公共异步任务RenderToStringAsync(字符串视图名称,对象模型)
{
var actionContext=new actionContext(_httpContext,new RouteData(),new ActionDescriptor());
var viewEngineResult=\u razorViewEngine.FindView(actionContext,viewName,false);
if(viewEngineResult.View==null | |(!viewEngineResult.Success))
{
抛出新ArgumentNullException($“找不到视图“{viewName}”);
}
var view=viewEngineResult.view;
使用(var sw=new StringWriter())
{
var viewDictionary=new ViewDataDictionary(new EmptyModelMetadataProvider(),new ModelStateDictionary());
viewDictionary.Model=Model;
var tempData=new TempDataDictionary(_httpContext,_tempDataProvider);
var viewContext=newviewcontext(actionContext、view、viewDictionary、tempData、sw、newhtmlhelpropoptions());
viewContext.RouteData=\u httpContext.GetRouteData();//在此处设置路由数据
wait view.RenderAsync(viewContext);
返回sw.ToString();
}
}
}
3.read.cshtml文件和返回字符串:

public class HomeController : Controller
{
    private readonly IViewRenderService _viewRenderService;
    public HomeController(IViewRenderService viewRenderService)
    {
        _viewRenderService = viewRenderService;
    }
    public IActionResult Index()
    {
        var data = new Users()
        {
            UserId = 1
        };
        return View(data);
    }
    public async Task<IActionResult> Privacy()
    {
        var data = new Users()
        {
            UserId = 1
        };
        var result = await _viewRenderService.RenderToStringAsync("Home/Index", data); 
        return Content(result);           
    }
公共类HomeController:控制器
{
私有只读IViewRenderService _viewRenderService;
公共家庭控制器(IViewRenderService viewRenderService)
{
_viewRenderService=viewRenderService;
}
公共IActionResult索引()
{
var data=新用户()
{
UserId=1
};
返回视图(数据);
}
公共异步任务隐私()
{
var data=新用户()
{
UserId=1
};
var result=wait_viewRenderService.RenderToStringAsync(“主/索引”,数据);
返回内容(结果);
}
4.Index.cshtml:

@model Users
<form>
    <label asp-for="UserId"></label>
    <br />
    <input asp-for="UserId" class="form-control" maxlength="4" />
    <span asp-validation-for="UserId" class="text-danger"></span>
    <input type="submit" value="create" />
</form>
@模型用户

5.注册服务:

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddScoped<IViewRenderService, ViewRenderService>();
services.AddSingleton();
services.addScope();

大概还有tostring()方法调用将返回html并解析模型变量?我可以试试。它会的。您可以简单地返回视图,然后返回一个对象。因此,是的,您可以将其用作普通的局部视图。如果您在Core 3.0+上使用端点路由,这将不起作用,因为在执行
新建ActionContext()
时,没有任何iRouting与请求关联。