How to “download” from data: URIs?

寵の児 提交于 2020-01-11 10:28:08

问题


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?

I need this because I want to display a XAML file generated from SVG, which includes some images using data: URIs. I don't want to always parse the XAML, save the images to disk and then change the XAML to point to the files. I believe WPF uses WebRequest internally to get those images.


回答1:


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.



来源:https://stackoverflow.com/questions/14779497/how-to-download-from-data-uris

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!