Beispiel #1
0
        /// <summary>
        /// 创建网络请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="method">方法</param>
        /// <param name="data">写入的数据</param>
        /// <param name="refer">引用页</param>
        /// <param name="saveToFile">保存文件地址</param>
        /// <param name="streamInvoker">流读取对象,仅当返回结果为流时可用</param>
        /// <param name="async">是否是异步发送</param>
        /// <param name="result">预先设置结果类型</param>
        /// <param name="isXhr">是否增加AJAX请求头标记</param>
        /// <param name="contextData">关联的上下文数据</param>
        /// <param name="headers">要跟随请求一起发送的HTTP标头</param>
        /// <param name="contentType">设置当发送对象类型时,设置发送类型。不设置或传递null值将会自动判断</param>
        /// <param name="allowAutoRedirect">是否允许自动重定向</param>
        /// <param name="targetStream">要写入的目标流</param>
        /// <param name="extra">额外的请求数据</param>
        /// <typeparam name="TResult">结果类型</typeparam>
        /// <returns></returns>
        public HttpContext <TResult> Create <TResult>(
            HttpMethod method,
            string url,
            string refer      = null,
            object data       = null,
            TResult result    = default(TResult),
            string saveToFile = null,
            EventHandler <ResponseStreamContent.RequireProcessStreamEventArgs> streamInvoker = null,
            bool async = false,
            bool?isXhr = null,
            Dictionary <string, object> contextData = null,
            WebHeaderCollection headers             = null,
            ContentType?contentType = null,
            bool?allowAutoRedirect  = null,
            Stream targetStream     = null,
            ExtraRequestInfo extra  = null
            ) where TResult : class
        {
            contextData = contextData ?? new Dictionary <string, object>();
            var uri = ResolveUri(null, url, contextData);

            if (uri == null)
            {
                return(null);
            }

            return(Create(method, uri, refer, data, result, saveToFile, streamInvoker, async, isXhr, contextData, headers, contentType, allowAutoRedirect, targetStream, extra));
        }
Beispiel #2
0
 public HttpContext <TResult> Create <TResult>(
     HttpMethod method,
     Uri uri,
     Uri refer,
     object data       = null,
     TResult result    = default(TResult),
     string saveToFile = null,
     EventHandler <ResponseStreamContent.RequireProcessStreamEventArgs> streamInvoker = null,
     bool async = false,
     bool?isXhr = null,
     Dictionary <string, object> contextData = null,
     WebHeaderCollection headers             = null,
     ContentType?contentType = null,
     bool?allowAutoRedirect  = null,
     Stream targetStream     = null,
     ExtraRequestInfo extra  = null
     ) where TResult : class => Create <TResult>(method, uri, refer?.OriginalString, data, result, saveToFile, streamInvoker, async, isXhr, contextData, headers, contentType, allowAutoRedirect, targetStream, extra);
 /// <summary>
 /// 创建 <see cref="RequestWrapRequestContentEventArgs" />  的新实例(RequestWrapRequestContentEventArgs)
 /// </summary>
 /// <param name="httpClient"></param>
 /// <param name="data"></param>
 /// <param name="extraRequestInfo">额外的请求信息</param>
 public RequestWrapRequestContentEventArgs(HttpClient httpClient, object data, ExtraRequestInfo extraRequestInfo)
 {
     HttpClient       = httpClient;
     Data             = data;
     ExtraRequestInfo = extraRequestInfo;
 }
Beispiel #4
0
        /// <summary>
        /// 创建网络请求
        /// </summary>
        /// <param name="uri">请求地址</param>
        /// <param name="method">方法</param>
        /// <param name="data">写入的数据</param>
        /// <param name="refer">引用页</param>
        /// <param name="saveToFile">保存文件地址</param>
        /// <param name="streamInvoker">流读取对象,仅当返回结果为流时可用</param>
        /// <param name="async"></param>
        /// <param name="result"></param>
        /// <param name="isXhr"></param>
        /// <param name="contextData">关联的上下文数据</param>
        /// <param name="headers">额外的要发出去的标头</param>
        /// <param name="contentType">设置当发送对象类型时,设置发送类型</param>
        /// <param name="allowAutoRedirect">设置当服务器发送3xx代码时是否自动跟踪跳转</param>
        /// <param name="targetStream">要写入的目标流</param>
        /// <param name="extra">额外的请求数据</param>
        /// <typeparam name="TResult">结果类型</typeparam>
        /// <returns></returns>
        public HttpContext <TResult> Create <TResult>(
            string method,
            Uri uri,
            string refer      = null,
            object data       = null,
            TResult result    = default(TResult),
            string saveToFile = null,
            EventHandler <ResponseStreamContent.RequireProcessStreamEventArgs> streamInvoker = null,
            bool async = false,
            bool?isXhr = null,
            Dictionary <string, object> contextData = null,
            WebHeaderCollection headers             = null,
            ContentType?contentType = null,
            bool?allowAutoRedirect  = null,
            Stream targetStream     = null,
            ExtraRequestInfo extra  = null
            ) where TResult : class
        {
            if (string.IsNullOrEmpty(method))
            {
                throw new ArgumentException($"{nameof(method)} is null or empty.", nameof(method));
            }
            if (uri == null)
            {
                throw new ArgumentNullException(nameof(uri), $"{nameof(uri)} is null.");
            }

            if (typeof(TResult) == typeof(object))
            {
                throw new InvalidOperationException("context type cannot be object.");
            }

            contextData = contextData ?? new Dictionary <string, object>();
            method      = method.ToUpper();

            var resultType = typeof(TResult);

            if (streamInvoker != null && typeof(Stream) == resultType)
            {
                throw new InvalidOperationException("非流结果时不可设置流操作");
            }

            var referUri = Setting.ResolveReferUri ? ResolveUri(HttpRequestHeader.Referer, refer, contextData) : null;
            var request  = new HttpRequestMessage(uri, method)
            {
                Referer = referUri?.OriginalString ?? refer
            };

            if (data != null)
            {
                request.RequestData = WrapRequestContent(data, contentType, extra);
            }
            else if (request.AllowRequestBody)
            {
                request.RequestData = new RequestByteBufferContent(new byte[0]);
            }
            request.Async = async;

            var ctx = HttpHandler.GetContext <TResult>(this, request);

            Setting.InitializeHttpContext(ctx);

            //自动设置格式
            if (request.ExceptType == null)
            {
                request.ExceptType = GetPreferedResponseType(ctx, streamInvoker, result, targetStream, saveToFile);
            }
            request.ExtraRequestInfo = extra;
            if (isXhr != null)
            {
                request.AppendAjaxHeader = isXhr.Value;
            }
            ctx.ContextData           = contextData;
            request.Headers           = headers;
            request.AllowAutoRedirect = allowAutoRedirect ?? Setting.AllowAutoDirect;

            return(ctx);
        }
Beispiel #5
0
        /// <summary>
        /// 对请求数据进行包装,转换为合适的请求类型,并返回对应的负载类型
        /// </summary>
        /// <param name="data">要发送的数据</param>
        /// <param name="contentType">对应的负载类型</param>
        /// <param name="extraRequestInfo">额外的请求数据</param>
        /// <returns>经过包装的 <see cref="HttpRequestContent"/> 对象</returns>
        public virtual HttpRequestContent WrapRequestContent(object data, ContentType?contentType, ExtraRequestInfo extraRequestInfo)
        {
            if (data == null)
            {
                return(null);
            }

            var type = contentType ?? GetPreferContentType(data.GetType()) ?? Setting.DefaultRequestContentType;
            var ea   = new RequestWrapRequestContentEventArgs(this, data, extraRequestInfo)
            {
                ContentType = type
            };

            ea.RequestContent = Setting.ContentPayloadBuilder.WrapRequestContent(data, ea);

            GlobalEvents.OnBeforeRequestWrapRequestContent(this, ea);
            OnBeforeWrapRequestContent(this, ea);
            var content = ea.RequestContent;

            contentType = ea.ContentType;

            if (content == null)
            {
                if (data is HttpRequestContent)
                {
                    content = data as HttpRequestContent;
                }
                else if (data is string)
                {
                    content = new RequestStringContent(data as string, type);
                }
                else if (data is Stream)
                {
                    content = new RequestCopyStreamContent(data as Stream, type);
                }
                else if (data is byte[])
                {
                    content = new RequestByteBufferContent(data as byte[], contentType: type);
                }
                else if (data is IDictionary <string, string> && type != ContentType.Json)
                {
                    content = new RequestFormDataContent(data as IDictionary <string, string>, type);
                }
                else if (data is XmlDocument || data is XmlNode || data is System.Xml.Linq.XDocument)
                {
                    content = new RequestXmlContent(data, contentType ?? ContentType.Xml);
                }
                //object

                else if (contentType == ContentType.Json)
                {
                    content = new RequestJsonContent(data);
                }
                else if (contentType == ContentType.Xml)
                {
                    content = new RequestXmlContent(data, type);
                }
                else
                {
                    content = new RequestObjectContent <object>(data, type);
                }
            }

            //全局事件
            GlobalEvents.OnRequestWrapRequestContent(this, ea);

            //实例事件
            OnRequestWrapRequestContent(this, ea);

            content = HttpHandler.WrapRequestContent(this, content, data, contentType);

            return(content);
        }
Beispiel #6
0
        /// <summary>
        /// 获得对应的数据处理类
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="streamInvoker"></param>
        /// <param name="result"></param>
        /// <param name="targetStream">目标流</param>
        /// <param name="saveToFilePath">希望保存到的目标文件路径</param>
        /// <param name="extraRequestInfo">额外的请求数据信息</param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public virtual HttpResponseContent GetPreferedResponseType <T>(HttpContext ctx, EventHandler <ResponseStreamContent.RequireProcessStreamEventArgs> streamInvoker = null, T result = default(T), Stream targetStream = null, string saveToFilePath = null, ExtraRequestInfo extraRequestInfo = null)
        {
            var resultType = typeof(T);
            var ea         = new GetPreferedResponseTypeEventArgs <T>(this, ctx, result, saveToFilePath, streamInvoker, targetStream, extraRequestInfo);

            ea.ResponseContent = Setting.ContentPayloadBuilder.GetResponseContent(result, ea);

            GlobalEvents.OnBeforeRequestGetPreferedResponseType(this, ea);
            OnBeforeRequestGetPreferedResponseType(this, ea);
            var content = ea.ResponseContent;

            if (content == null)
            {
                if (!saveToFilePath.IsNullOrEmpty())
                {
                    content = new ResponseFileContent(ctx, this, saveToFilePath);
                }
                else if (resultType != typeof(object))
                {
                    if (resultType == typeof(string))
                    {
                        content = new ResponseStringContent(ctx, this);
                    }
                    else if (resultType == typeof(byte[]))
                    {
                        content = new ResponseBinaryContent(ctx, this);
                    }
                    else if (resultType == typeof(Image))
                    {
                        content = new ResponseImageContent(ctx, this);
                    }
                    else if (resultType == typeof(XmlDocument))
                    {
                        content = new ResponseXmlContent(ctx, this, (XmlDocument)(object)result);
                    }
                    else if (resultType == typeof(EventHandler <ResponseStreamContent.RequireProcessStreamEventArgs>))
                    {
                        var r = new ResponseStreamContent(ctx, this);
                        if (streamInvoker != null)
                        {
                            r.RequireProcessStream += streamInvoker;
                        }
                        content = r;
                    }
                    else if (resultType == typeof(Stream))
                    {
                        content = new ResponseCopyStreamContent(ctx, this, targetStream ?? new MemoryStream());
                    }
                    else
                    {
                        content = new ResponseObjectContent <T>(ctx, this)
                        {
                            ObjectInternal = result
                        }
                    };
                }
                else
                {
                    content = null;                     //为null,等待请求自动判断
                }
                ea.ResponseContent = content;
            }

            //Global events
            GlobalEvents.OnRequestGetPreferedResponseType(this, ea);

            //instance events
            OnRequestGetPreferedResponseType(this, ea);

            //http handler
            HttpHandler.GetPreferedResponseType <T>(this, ctx, content, streamInvoker, result, targetStream);

            return(content);
        }
Beispiel #7
0
 /// <summary>
 /// 创建 <see cref="GetPreferedResponseTypeEventArgs" />  的新实例(GetPreferedResponseTypeEventArgs)
 /// </summary>
 /// <param name="httpClient">当前的客户端</param>
 /// <param name="httpContext">当前的上下文环境</param>
 /// <param name="targetObject">已有目标数据</param>
 /// <param name="saveToFilePath">要将当前请求写入的文件路径</param>
 /// <param name="streamInvoker">处理当前数据片段的事件处理句柄</param>
 /// <param name="targetStream">要写入的目标流</param>
 internal GetPreferedResponseTypeEventArgs(HttpClient httpClient, HttpContext httpContext, T targetObject, string saveToFilePath, EventHandler <ResponseStreamContent.RequireProcessStreamEventArgs> streamInvoker, Stream targetStream, ExtraRequestInfo extraRequestInfo)
     : base(httpClient, httpContext, typeof(T), targetObject, saveToFilePath, streamInvoker, targetStream, extraRequestInfo)
 {
 }