ASP.NET中注册前缀Uri方法及data URI请求处理问题咨询
关于ASP.NET中Uri前缀注册与Data URI处理的问题解答
首先先把你提供的GetUrl方法代码贴出来:
static public byte[] GetUrl(string url) { byte[] buf; try { WebProxy myProxy = new WebProxy(); IWebRequestCreate req = (IWebRequestCreate)WebRequest.Create(url); //WebRequest reqw = WebRequest.Create(req); WebResponse response = req.GetResponse(); stream = response.GetResponseStream(); using (BinaryReader br = new BinaryReader(stream)) { int len = (int)(response.ContentLength); buf = br.ReadBytes(len); br.Close(); } stream.Close(); response.Close(); } catch (Exception exp) { buf = null; } return (buf); }
接下来逐个解决你的问题:
1. 如何在ASP.NET中创建注册前缀Uri?
要自定义并注册Uri前缀,核心是用WebRequest.RegisterPrefix方法,配合实现IWebRequestCreate接口来处理自定义前缀的请求,步骤如下:
第一步:实现IWebRequestCreate接口
这个接口只需要实现Create方法,返回一个WebRequest的子类(或者你自定义的请求处理类),用来处理对应前缀的请求逻辑。比如我们要注册一个myapp://前缀:public class MyAppWebRequestCreator : IWebRequestCreate { public WebRequest Create(Uri uri) { // 这里写你处理自定义前缀请求的逻辑,比如返回自定义的WebRequest子类 return new MyAppWebRequest(uri); } } // 自定义WebRequest子类,处理具体请求 public class MyAppWebRequest : WebRequest { private readonly Uri _uri; public MyAppWebRequest(Uri uri) => _uri = uri; public override WebResponse GetResponse() { // 模拟返回响应,比如根据uri返回对应的数据 return new MyAppWebResponse(_uri); } } public class MyAppWebResponse : WebResponse { private readonly Uri _uri; public MyAppWebResponse(Uri uri) => _uri = uri; public override Stream GetResponseStream() { // 这里返回你自定义的响应流,比如根据uri返回对应的内容 return new MemoryStream(Encoding.UTF8.GetBytes($"处理自定义前缀请求:{_uri.ToString()}")); } }第二步:注册前缀
在应用启动的时候(比如Global.asax的Application_Start方法里),调用WebRequest.RegisterPrefix完成注册:WebRequest.RegisterPrefix("myapp://", new MyAppWebRequestCreator());这样之后,当你调用
WebRequest.Create("myapp://some/path")时,就会使用你自定义的MyAppWebRequestCreator来处理请求了。
2. 如何处理Data URI并获取响应?
你的GetUrl方法之所以处理不了data URI,是因为默认的WebRequest只支持http/https/file等标准前缀,并没有内置处理data URI的逻辑——而且data URI本质上是内嵌的base64数据,根本不需要发起网络请求,直接解析就行。
我们可以修改GetUrl方法,增加对data URI的判断和解析逻辑:
修改后的完整方法
static public byte[] GetUrl(string url) { byte[] buf = null; try { // 先判断是否是data URI if (url.StartsWith("data:", StringComparison.OrdinalIgnoreCase)) { // 解析data URI的结构:data:[<mediatype>][;base64],<data> var parts = url.Split(new[] { ',' }, 2); if (parts.Length != 2) throw new FormatException("无效的Data URI格式"); var headerPart = parts[0]; var dataPart = parts[1]; // 判断是否是base64编码 bool isBase64 = headerPart.EndsWith(";base64", StringComparison.OrdinalIgnoreCase); if (isBase64) { // 解码base64数据 buf = Convert.FromBase64String(dataPart); } else { // 普通的url编码数据,这里简单处理,实际可能需要解码url编码 buf = Encoding.UTF8.GetBytes(Uri.UnescapeDataString(dataPart)); } } else { // 处理普通的HTTP/HTTPS等URL,保留你原来的逻辑(修正了资源释放的问题) WebRequest req = WebRequest.Create(url); using (WebResponse response = req.GetResponse()) using (Stream stream = response.GetResponseStream()) using (BinaryReader br = new BinaryReader(stream)) { int len = (int)response.ContentLength; buf = br.ReadBytes(len); } } } catch (Exception exp) { // 建议在这里添加日志记录,方便排查问题 buf = null; } return buf; }
关键说明:
- 原代码里有个小问题:
stream变量未声明,我在修改后的代码里用using语句自动释放资源,比手动Close()更安全可靠。 - data URI的解析逻辑:先拆分头部和数据部分,判断是否是base64编码,然后直接解码得到byte数组,完全不需要走WebRequest的网络请求流程。
- 如果一定要用
IWebRequestCreate来处理data URI,也可以注册一个自定义的Creator,在Create方法里直接解析data URI并返回对应的WebResponse,但其实没必要——直接解析更简单高效。
内容的提问来源于stack exchange,提问作者divikdiya
相关产品推荐
相关产品推荐

