Как мне разрешить HttpContext из RegisterEvent, чтобы получить представление в строке в ядре asp.net 3 и Electron.net? - PullRequest
0 голосов
/ 31 октября 2019

Я пробовал внедрение зависимости, но это всегда дает мне HttpContextAccessor.Current или ActionContext как ноль, потому что я не в состоянии запроса (я думаю). Итак, как я могу получить этот контекст, чтобы просто взять представление, преобразовать его в строку html (с моделью при необходимости) и выбросить обратно в JS? Я даже пытался напрямую вызвать действие Controller, но оно всегда дает HttpContext как ноль ... Я использую Asp.NET Core 3.

Пожалуйста, если кто-то проходил, помогите мне :-)

Спасибо,

Редактировать:

У меня есть ядро ​​asp.net на базе Electron.net для настольного приложения. Я использую много IPC-коммуникаций для извлечения данных из бэкэнда c #, используя Electron.IpcMain.On. Я регистрирую действие как слушатель в c # в классе. Основная проблема заключается в том, что этот класс действительно находится за пределами обычного HttpRequest или контроллера. Вот пример кода:

IpcBase Class

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 на контроллере, который получает представление в String (у меня уже есть это, но не с 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 (в основном взято отсюда Создать строку из вида )

Добавлено при запуске:

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

Когда я создаю экземпляр IpcUI, DI предоставляет мне услугу, но без какого-либо HttpContext или ActionContext ... Извините за отсутствие информации из моего последнего редактирования :-). Надеюсь, это немного конкретнее.

О! Я что-то забыл, IpcUI создается во время выполнения не с новым (потому что это не работает), но с пользовательской функцией расширения, которая извлекает IServiceProvider для DI:

При запуске

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)); 
        }
...