How to “download” from data: URIs?

前端 未结 1 1633
花落未央
花落未央 2021-01-21 18:03

I have a data: URI that I need to “download” (read: load as a stream or byte array) using the normal .Net WebClient/WebRequest. How can I do that?

相关标签:
1条回答
  • 2021-01-21 18:21

    You can use WebRequest.RegisterPrefix() to do that. You will need to implement IWebRequestCreate that returns a custom WebRequest that returns a custom WebResponse, which can finally be used to get the data from the URI. It could look like this:

    public class DataWebRequestFactory : IWebRequestCreate
    {
        class DataWebRequest : WebRequest
        {
            private readonly Uri m_uri;
    
            public DataWebRequest(Uri uri)
            {
                m_uri = uri;
            }
    
            public override WebResponse GetResponse()
            {
                return new DataWebResponse(m_uri);
            }
        }
    
        class DataWebResponse : WebResponse
        {
            private readonly string m_contentType;
            private readonly byte[] m_data;
    
            public DataWebResponse(Uri uri)
            {
                string uriString = uri.AbsoluteUri;
    
                int commaIndex = uriString.IndexOf(',');
                var headers = uriString.Substring(0, commaIndex).Split(';');
                m_contentType = headers[0];
                string dataString = uriString.Substring(commaIndex + 1);
                m_data = Convert.FromBase64String(dataString);
            }
    
            public override string ContentType
            {
                get { return m_contentType; }
                set
                {
                    throw new NotSupportedException();
                }
            }
    
            public override long ContentLength
            {
                get { return m_data.Length; }
                set
                {
                    throw new NotSupportedException();
                }
            }
    
            public override Stream GetResponseStream()
            {
                return new MemoryStream(m_data);
            }
        }
    
        public WebRequest Create(Uri uri)
        {
            return new DataWebRequest(uri);
        }
    }
    

    This supports only base64 encoding, but support for URI encoding could be easily added.

    You then register it like this:

    WebRequest.RegisterPrefix("data", new DataWebRequestFactory());
    

    And yes, this does work for retrieving data: images in XAML files.

    0 讨论(0)
提交回复
热议问题