我正在使用 Blazor Hybrid 编写 WPF 应用程序。我正在将一个用 ASP.NET Core 编写的 Web 应用程序转变为仅本地应用程序。
我的网络应用程序有一些图像,它们会在控制器中动态生成。您可以通过本地 http 调用在 html 中显示它们,例如
<img src="/dynamic-imgs/387854.png" />
。
在 asp.net core 中,这很容易,但在 Blazor Hybrid 中,我不知道如何向 url 提供数据。在我的 WPF 版本中,我将如何根据 url 向 WebView 提供动态数据?
我最接近解决此问题的方法是按照下面的演示拦截 WebView2 组件发出的调用。 (出于演示的目的,我没有动态生成图像,而是从文件系统中提取它们)。
此解决方案允许我拦截从 0.0.0.0 以外的域调用的图像,例如
https://somedomain/img/someimage.png
。如果我尝试对 0.0.0.0 (/img/someimage.png
) 执行相同操作,则会出现“未找到”错误。我推测在后一种情况下,Blazor 路由系统在我处理完后会妨碍响应。WebResourceRequested
此代码依赖于以下
var rootPath = "https://0.0.0.0/imgs/"; //this doesn't work.
var rootPath = "https://demo/imgs/"; //this works
webView.CoreWebView2.AddWebResourceRequestedFilter($"{rootPath}*", CoreWebView2WebResourceContext.All);
webView.CoreWebView2.WebResourceRequested += delegate (object? sender,
CoreWebView2WebResourceRequestedEventArgs args)
{
if (!args.Request.Uri.StartsWith($"{rootPath}")) return;
string assetsFilePath = "E:\IMAGES" +
args.Request.Uri.Substring($"{rootPath}*".Length - 1);
try
{
var deferral = args.GetDeferral();
if (File.Exists(assetsFilePath)){
}
FileStream fs = File.OpenRead(assetsFilePath);
ManagedStream ms = new ManagedStream(fs);
string headers = "";
if (assetsFilePath.EndsWith(".png"))
{
headers = "Content-Type: image/png";
}
args.Response = webView.CoreWebView2.Environment.CreateWebResourceResponse(ms, 200, "OK", headers);
deferral.Complete();
}
catch (Exception e)
{
args.Response = webView.CoreWebView2.Environment.CreateWebResourceResponse(
null, 404, "Not found", "");
}
};
类
ManagedStream
public class ManagedStream : Stream
{
public ManagedStream(Stream s)
{
s_ = s;
}
public override bool CanRead => s_.CanRead;
public override bool CanSeek => s_.CanSeek;
public override bool CanWrite => s_.CanWrite;
public override long Length => s_.Length;
public override long Position { get => s_.Position; set => s_.Position = value; }
public override void Flush()
{
throw new NotImplementedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
return s_.Seek(offset, origin);
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
public override int Read(byte[] buffer, int offset, int count)
{
int read = 0;
try
{
read = s_.Read(buffer, offset, count);
if (read == 0)
{
s_.Dispose();
}
}
catch
{
s_.Dispose();
throw;
}
return read;
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}
private Stream s_;
}
如果您的图像位于其他地方,您可以这样做:
<img src="dynamic-imgs/387854.png" />
如果内存中有图像并且不想将其保存到磁盘,您可以将其转换为 Base64 字符串并直接提供:
<img src="e:/images/dynamic-imgs/387854.png" />