簡體   English   中英

在 C# 中以字符串形式返回視圖組件的結果

[英]Return the result of View Component as a string in C#

我有一個服務,它生成電子郵件並返回一個字符串。 但是,我有一個視圖組件,我通常從我的視圖中調用它,並將結果附加到一個已經存在的字符串中:

string result = @await Component.InvokeAsync("Widget", new { widgetZone = "stock_levels_summary_cart_price", additionalData = product.Id })
sb.AppendLine($"<td style=\"padding: 0.6em 0.4em;text-align: center;\">{result}</td>");

如何在我的服務中調用此視圖組件並將結果傳遞到我可以在我的電子郵件服務中使用的字符串變量中?

我能夠通過為視圖組件創建局部視圖來實現這一點。

在局部視圖中,我聲明了我的視圖組件:

@model int

@await Component.InvokeAsync("Widget", new { widgetZone = "stock_levels_summary_cart_price", additionalData = Model})

在我的控制器中,我創建了一個動作,如下所示:

public virtual PartialViewResult OrderDetailsStocklevel(int productId)
{
    return PartialView("~/Views/Shared/_OrderDetailsStocklevel.cshtml", productId);
}

然后我實現了一個服務來呈現部分視圖內容並返回結果:

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 Nop.Services.Helpers
    {

        public interface IViewRenderHelper
        {
            string RenderToString(string viewName, object model, string viewPath);
        }

    public class ViewRenderHelper : IViewRenderHelper
    {
        private readonly IServiceProvider _serviceProvider;

        public ViewRenderHelper(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
        }

        public string RenderToString(string viewName, object model, string viewPath)
        {
            var httpContext = new DefaultHttpContext { RequestServices = _serviceProvider };
            var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());

            var engine = _serviceProvider.GetService(typeof(IRazorViewEngine)) as IRazorViewEngine;
            var tempDataProvider = _serviceProvider.GetService(typeof(ITempDataProvider)) as ITempDataProvider;

            if (engine == null)
            {
                throw new Exception("Can't find IRazorViewEngine");
            }


            var viewEngineResult = engine.FindView(actionContext, viewPath, false);

            if (!viewEngineResult.Success)
            {
                throw new InvalidOperationException($"Couldn't find view '{viewName}'");
            }

            var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())
            {
                Model = model
            };


            using (var output = new StringWriter())
            {
                var viewContext = new ViewContext(actionContext, viewEngineResult.View,
                    viewDictionary, new TempDataDictionary(actionContext.HttpContext, tempDataProvider),
                    output, new HtmlHelperOptions());

                viewEngineResult.View.RenderAsync(viewContext).GetAwaiter().GetResult();

                return output.ToString();
            }



        }
    }
}

然后,為了加載從視圖組件創建的局部視圖,我執行了如下方法:

var stockLevelLabel = _viewRenderService.RenderToString("stocklevel", orderItem.ProductId, "_OrderDetailsStocklevel");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM