#asp.net #angular #asp.net-core #asp.net-web-api #webview2
Вопрос:
В настоящее время я разрабатываю веб-клиент Angular SPA с поддержкой .NET5 REST. Все это находится в одном проекте Visual Studio, и он отлично строится / работает.
Сейчас я изучаю возможность распространения этого приложения в качестве настольного приложения для Windows. Я смог получить Electron.NET работать, но это похоже на обходное решение (узел?!). Мне также не особенно понравилось, что ресурсы были видны/изменяемы в распределенном приложении.
Это побудило меня исследовать использование WebView2 в WPF (Microsoft, похоже, делает аналогичный переход с MSTeams). Я нашел несколько примеров, но они используют только:
- исключительно удаленный контент («www.bing.com»)
- локальный контент, но только img / html / и т. Д
- почтовая рассылка и т. Д. Для связи с использованием пользовательских объектов.
Ничего из этого я не хочу. Ну, это не совсем так. Мне нужно #2 для загрузки углового СПА, но когда угловой, размещенный в WebView2, вызывает HttpClient, я хотел бы перехватить этот запрос в главном приложении и направить его на мои контроллеры REST. Это позволило бы мне сохранить почти весь мой код нетронутым и, по-видимому, отправить меньший, более запутанный exe-файл.
Возможно ли это? очевидно? Является ли мое желание в корне ошибочным? (это было бы не в первый раз)
Комментарии:
1. Возможно, вас заинтересует github.com/amaitland/Chromium. AspNetCore.Bridge существует пример WebView2, демонстрирующий прием запросов браузера и их выполнение непосредственно с помощью asp net core. nuget.org/packages/Chromium. AspNetCore.Мост
2. @amaitland, это «сработало здорово», как говорится. У меня все еще есть еще кое-какая работа с точки зрения 1) наличия оболочки WPF в другой сборке и 2) обеспечения того, чтобы angular действительно работал в развертывании. Но, с точки зрения заданного вопроса, это было именно то, что мне было нужно. Какая замечательная библиотека!
3. Отлично! Если есть дополнительные примеры, которые вы хотели бы добавить, то запрос на извлечение будет наиболее желанным.
Ответ №1:
Хром.AspNetCore.Bridge предлагает решение этой проблемы. Он использует owin для размещения кода на стороне сервера в памяти и предоставляет интерпретатор запросов для чистой ретрансляции всех запросов в код «сервера».
По ссылке выше приведены рабочие примеры, но вкратце:
Приложение.xaml.cs:
private IWebHost _host;
private AppFunc _appFunc;
public AppFunc AppFunc
{
get { return _appFunc; }
}
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development");
_ = Task.Run(async () =>
{
var builder = new WebHostBuilder();
builder.ConfigureServices(services =>
{
var server = new OwinServer();
server.UseOwin(appFunc =>
{
_appFunc = appFunc;
});
services.AddSingleton<IServer>(server);
});
_host = builder
.UseStartup<Startup>()
.UseContentRoot(Directory.GetCurrentDirectory())
.Build();
await _host.RunAsync();
});
}
Главное окно.xaml.cs
private AppFunc _appFunc;
public MainWindow()
{
InitializeComponent();
Browser.CoreWebView2InitializationCompleted = Browser_CoreWebView2InitializationCompleted;
}
private void Browser_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
{
if (e.IsSuccess)
{
_appFunc = ((App)Application.Current).AppFunc;
Browser.CoreWebView2.WebResourceRequested = BrowserWebResourceRequestedAsync;
Browser.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);
}
}
private async void BrowserWebResourceRequestedAsync(object sender, CoreWebView2WebResourceRequestedEventArgs e)
{
var deferral = e.GetDeferral();
var request = new ResourceRequest(e.Request.Uri, e.Request.Method, e.Request.Headers, e.Request.Content);
var response = await RequestInterceptor.ProcessRequest(_appFunc, request);
var coreWebView2 = (CoreWebView2)sender;
e.Response = coreWebView2.Environment.CreateWebResourceResponse(response.Stream, response.StatusCode, response.ReasonPhrase, response.GetHeaderString());
deferral.Complete();
}