我找不到在SignalR集线器内呈现局部视图的方法,真正的问题是我不知道如何将局部视图转换为字符串.

我制作了一个从我的数据库中呈现一些数据的表的一部分,我希望这些数据每2分钟刷新一次,为此我使用了SignalR集线器.但我需要将我的部分作为字符串传递给集线器,否则它将无法工作.有什么主意吗?

集线器代码(我试图使用一个函数,但它不起作用):

    public async Task<string> Teste()
    {
        var body = await _renderer.RenderPartialToStringAsync("../Areas/Admin/Pages/Partial/_Filas.cshtml", new principalModel());
        return body.ToString();
    }

推荐答案

您可以使用此类将视图渲染为字符串:

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;

namespace RenderView.Models
{
    public class ViewRenderer
    {
        private readonly IRazorViewEngine _viewEngine;
        private readonly ITempDataProvider _tempDataProvider;
        private readonly IServiceProvider _serviceProvider;
        private readonly IHttpContextAccessor _httpContextAccessor;

        public ViewRenderer(
            IRazorViewEngine viewEngine,
            ITempDataProvider tempDataProvider,
            IServiceProvider serviceProvider,
            IHttpContextAccessor httpContextAccessor)
        {
            _viewEngine = viewEngine;
            _tempDataProvider = tempDataProvider;
            _serviceProvider = serviceProvider;
            _httpContextAccessor = httpContextAccessor;
        }


        public async Task<string> RenderViewToStringAsync<TModel>(string viewNameOrPath, TModel model)
        {
            var actionContext = GetActionContext();
            var view1 = _viewEngine.FindView(actionContext, viewNameOrPath, false);
            if (!view1.Success)
            {
                view1 = _viewEngine.GetView("~/", viewNameOrPath, false);
                if (!view1.Success)
                    throw new FileNotFoundException($"Couldn't find '{(object)viewNameOrPath}'");
            }

            var view2 = view1.View;
            await using var output = new StringWriter();
            var viewData = new ViewDataDictionary<TModel>((IModelMetadataProvider)new EmptyModelMetadataProvider(),
                new ModelStateDictionary())
            {
                Model = model
            };
            var context = new ViewContext(actionContext, view2, (ViewDataDictionary)viewData,
                (ITempDataDictionary)new TempDataDictionary(actionContext.HttpContext, this._tempDataProvider),
                (TextWriter)output, new HtmlHelperOptions());
            await view2.RenderAsync(context);
            var stringAsync = output.ToString();
            return stringAsync;
        }

        private ActionContext GetActionContext()
        {
            var httpContext = _httpContextAccessor?.HttpContext;
            if (httpContext != null)
                return new ActionContext(httpContext, httpContext.GetRouteData(), new ActionDescriptor());
            var defaultHttpContext = new DefaultHttpContext
            {
                RequestServices = this._serviceProvider
            };
            return new ActionContext((HttpContext)defaultHttpContext, new RouteData(), new ActionDescriptor());
        }
    }
}

您应该将下面这几行添加到启动:

builder.Services.AddMvcCore().AddRazorViewEngine();
builder.Services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
builder.Services.AddScoped<ViewRenderer>();

按如下方式使用ViewRender类:

   public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;
        private readonly ViewRenderer _viewRenderer;

        public HomeController(ILogger<HomeController> logger, ViewRenderer viewRenderer)
        {
            _logger = logger;
            _viewRenderer = viewRenderer;
        }

        public async Task<IActionResult> Index()
        {
            var renderedView =await 
                _viewRenderer.RenderViewToStringAsync<MyViewModel>("_MyView", new MyViewModel() { Id = 1 });
            ViewData["RenderedView"]= renderedView;
            return View();

        }
        public class MyViewModel
        {
            public int Id { get; set; }
        }
    }

Csharp相关问答推荐

Blazor:子编辑表单上的嵌套编辑表单验证

PredicateBuilder不是循环工作,而是手动工作

无法从具有一对多关系的C#类中使用Swagger创建记录

C#类主构造函数中的调试参数

使用特定格式的JsonConvert序列化对象

如何将ASP.NET Core 2.1(在.NET框架上运行)更新到较新的版本?

Blazor Web App WASM的两个独立项目令人困惑

将类移动到新命名空间后更新RavenDB Raven-Clr-Type

具有以接口为其类型的属性的接口;类指定接口的实现,但无效

为什么我可以用硬编码的集合而不是变量来设置没有setter的IList属性的值?

Lambda表达式如何与隐式强制转换一起工作?

在字符串C#之前获取数字

等待一个等待函数

如何在.NET Maui中将事件与MVVM一起使用?

如何强制新设置在Unity中工作?

发布.NET 8 Blazor WebAssembly独立应用程序以进行静态站点部署

如何在更新数据库实体时忽略特定字段?

如何处理ASP.NET Core中包含两个构造函数的控制器?

为什么INTEGER在通过反射调用时对空对象返回TRUE,而在INTEGER上调用时返回FALSE?

如何在flutter dart中使用publicKey.xml文件进行rsa加密,我遇到了问题Exception:Could not parse BigInt