0

我已经尝试过依赖注入,但这总是给我一个HttpContextAccessor.CurrentActionContext为空,因为我不处于请求状态(我认为)。那么我怎样才能让这个上下文只取一个视图,将其转换为 html 字符串(如果需要,使用 Model)并将其扔回 JS 中?我什至尝试直接调用 Controller 操作,但它总是将 HttpContext 设为 null ...我使用的是 Asp.NET Core 3。

请,如果有人经历过,请帮助我:-)

谢谢,

编辑:

我有一个基于 Electron.net 的 asp.net 核心,用于桌面应用程序。我使用大量 IPC 通信从后端 c# 中检索数据,使用Electron.IpcMain.On. 我在类中的 c# 中将一个动作注册为侦听器。主要问题是这个类真的在一个普通的 HttpRequest 或一个控制器之外。这是一些示例代码:

IpcBase 类

public abstract class IpcBase: IBaseIpcCommunicationClass
    {
        /// <summary>
        /// Find a way to get rid of this and take more than the first window
        /// </summary>
        protected static BrowserWindow _mainWindow = Electron.WindowManager.BrowserWindows.First();
        /// <summary>
        /// Send an ipcEvent with a parameter class
        /// </summary>
        /// <param name="parameters">Parameters to fill</param>
        public void RegisterIpcEvent<T>(IpcRegisterModel<T> registerModel) => Electron.IpcMain.On(registerModel.key, o => registerModel.action((T)
            ((JObject)o).ToObject(typeof(T))));

        /// <summary>
        /// Send a reply inside a registerevent
        /// </summary>
        /// <typeparam name="T">Type of model</typeparam>
        /// <param name="model">model</param>
        public void SendReply<T>(IpcSendParamsModel<T> model)
        {
            if (!string.IsNullOrEmpty(model.replyTo))
            {
                Electron.IpcMain.Send(_mainWindow, model.replyTo, model);
            }
        }
...
}

IpcUI(获取控制器视图,就像控制器上的 ajax 调用以检索字符串中的视图一样(我已经有了,但没有使用 Ipc)

public class IpcUI: IpcBase
    {
        public IpcUI(IRazorViewToStringService razorViewRenderService)
        {
            Console.WriteLine("IpcUI::Constructor");
            RegisterIpcEvent(new IpcRegisterModel<IpcSendParamsModel<AjaxPartialModel>>("renderPartial", async (param) =>
            {                
            var param = new IpcSendParamsModel<AjaxPartialModel>("RenderPartial")
            {
                key = "renderPartial",
                model = new AjaxPartialModel()
                {
                    DataModel = "{items: [{\r\n            MaterialIcon: \"\",\r\n            Title: \"Games\",\r\n            Selectable: true,\r\n            Active: true,\r\n            Key: \"GAMES\",\r\n            BadgeCaption: \"new\",\r\n            BadgeValue: \"123\",\r\n            BadgeColor: \"red darken-1\",\r\n            BadgePartialLink: \"\",\r\n            BadgeContainerLink: \"\",\r\n            BadgeModelLink: \"\",\r\n            PartialLink: \"Home/Index\",\r\n            ContainerLink: \"#body-content\",\r\n            ModelLink: \"\"\r\n        }] }".JsonDeserialize<MenuModelHeader>(),
                    PartialName = "PartialViews/_TopMenu"
                }
            };

            try
            {                
                param.results =
                    await razorViewRenderService.CreateAndResolveInstanceFromGeneric().RenderViewToStringAsync($"~/Views/{param.model.PartialName}.cshtml",
                        param.model.DataModel);
            }
            catch (Exception e)
            {
                IpcClasses.ExceptionManager.SendException(this, e, $"IpcUI params: {param.model.JsonSerialize()}");
            }
            }));
        }
}

Razor Service(主要取自此处Generate string from view

在启动时添加:

services.AddHttpContextAccessor();
            services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
            services.AddScoped<IRazorViewToStringService, RazorRazorViewToStringService>();

当我创建 IpcUI 的实例时,DI 为我提供了服务,但没有任何 HttpContext 或 ActionContext ...抱歉我上次编辑时缺少信息 :-)。希望它更具体一点。

哦 !我忘记了一些事情,IpcUI 是在运行时创建的,而不是使用新的(因为它不起作用),而是使用自定义扩展函数来检索 DI 的 IServiceProvider:

在启动中

ExtensionsUtils.ServiceProvider = app.ApplicationServices;

在 ExtensionsUtils

/// <summary>
        /// This is called in configure services to get the collection of services in an extension static class
        /// </summary>
        public static IServiceProvider ServiceProvider { get; set; }

        /// <summary>
        /// Create a reference from type T with DI
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="o"></param>
        /// <returns></returns>
        public static T CreateAndResolveInstanceFromGeneric<T>(this T o)
        {
            return (T)ActivatorUtilities.CreateInstance<T>(ServiceProvider);
        }

编辑2:我试图IRazorViewToStringService从一个真正的控制器构造函数访问,它再次为空......我做错了什么???

private readonly IRazorViewToStringService _razorViewRenderService;

        public BaseController(IRazorViewToStringService razorViewRenderService)
        {
            _razorViewRenderService = razorViewRenderService;
        }
...
/// <summary>
        /// Return a success http code and a View rendered as string
        /// </summary>
        /// <param name="ViewName">Name of MVC View (or PartialView)</param>
        /// <param name="Model">Model to pass if any</param>
        /// <returns>JSON: { result: "type", description: "Html Code" }</returns>
        public async Task<ActionResult> CheckAndReturnView(string ViewName, object Model = null)
        {
            return Ok(await _razorViewRenderService.RenderViewToStringAsync(ViewName, Model)); 
        }
4

0 回答 0