【WCF Restful】C# HTTP請求示范及踩坑問題


1、Post Body傳多個參數

接口定義:(ResponseFormat與RequestFormat分別將相應參數序列化、請求參數反序列化)

[OperationContract]
[WebInvoke(UriTemplate = "api/fun2", Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
 string TestFun2(string p1,string p2);

實現:

public string TestFun2(string p1, string p2)
{
   return p1+p2; 
}

調用:

private void button1_Click(object sender, EventArgs e)
{
   try
   {
      string sUrl3 = "http://localhost:10086/api/fun2";
      string sBody2 = JsonConvert.SerializeObject(new { p1 = "1", p2 = "2" });

      string sBack = HttpHelper.HttpPost(sUrl3, sBody2);
   }
   catch (Exception ex)
   {}
}

 

2、Post Body傳對象

 接口定義:

[OperationContract]
[WebInvoke(UriTemplate = "api/fun", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, Method = "POST", BodyStyle = WebMessageBodyStyle.Bare)]
 string TestFun(TestModel data);

實現:

 public string TestFun(TestModel pars)
 {
    try
    {
       return pars.Test1 + pars.Test2;
    }
    catch (Exception ex)
    {}
}

調用:

private void button1_Click(object sender, EventArgs e)
{
   try
   {
      string sUrl = "http://localhost:10086/api/fun";
                
      TestModel model = new TestModel();
      model.Test1 = "1";
      model.Test2 = "2";

      string sBody = JsonConvert.SerializeObject(model);
               
      string sBack = HttpHelper.HttpPost(sUrl, sBody);
   }
   catch (Exception ex)
   { }
}

 

3、Post Header傳參

定義:

[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/api/Test/GetData2", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
string GetData2();

實現:

public string GetData2()
{ WebHeaderCollection headerCollection
= WebOperationContext.Current.IncomingRequest.Headers; string code = headerCollection.Get("code"); string token = headerCollection.Get("token"); // todo return "200"; }

調用:

private void btnTest2_Click(object sender, EventArgs e)
{
    try
    {
        string sUrl = "http://localhost:10086/api/Test/GetData2";
        
        Dictionary<string, string> header = new Dictionary<string, string>();
        header.Add("code", "cccccc");
        header.Add("token", "tttttt");
        
        string sBack = HttpHelper.Post(sUrl, header, "");
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

 

4、Get請求方式(ps:header傳參方式與POST異曲同工)

定義:

[OperationContract]
[WebGet(UriTemplate = "/api/Test/GetFun/{par1}/{par2}?code={code}&token={token}", ResponseFormat = WebMessageFormat.Json)]
string GetFunction(string par1, string par2, int code, string token);

實現:

public string GetFunction(string par1, string par2, int code, string token)
{
    return $"{par1},{par2},{code},{token}";
}

調用:

private void button1_Click(object sender, EventArgs e)
{
    try
    {
        string sUrl = string.Format("http://localhost:6323/api/Test/GetFun/{0}/{1}?code={2}&token={3}", "par111", "par222", "ccccc", "ttttt");
        string sBack = HttpHelper.Get(sUrl, null, null);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

 

“踩坑集合”:

 1、MVC,HttpPost,請求傳多個參數時,被請求的方法不支持類似 string sUser, string sPwd 的傳參方式(接收值都為null),要用模型、dynmic或HttpContext.Current.Request.Form["par1"]接收參數!!!

 2、請求參數中,參數數據類型不能為:DateTime(用string代替)、枚舉(用int代替)、byte[],否則請求返回400錯誤。

 3、請求參數中,Dictionary<T,V> 類型用 List<KeyValuePair<T,V>> 代替;在接口聲明的入參中,應使用 Dictionary<T,V> 才能接到。

 

HttpHelper.cs

public class HttpHelper
    {
        static HttpHelper()
        {
            ServicePointManager.MaxServicePoints = 4;
            ServicePointManager.MaxServicePointIdleTime = 10000;
            ServicePointManager.UseNagleAlgorithm = true;
            ServicePointManager.Expect100Continue = true;
            ServicePointManager.CheckCertificateRevocationList = true;
            ServicePointManager.DefaultConnectionLimit = 512; //默認2,ServicePointManager.DefaultPersistentConnectionLimit
        }

        /// <summary>
        /// Post
        /// </summary>
        /// <param name="url"></param>
        /// <param name="body"></param>
        /// <param name="contentType"></param>
        /// <returns></returns>
        public static string Post(string url, string body, string contentType = "application/json")
        {
            return HttpMethod("POST", url, body, contentType);
        }

        public static string Post(string url, Dictionary<string, string> headers, string body, string contentType = "application/json")
        {
            return HttpMethod("POST", url, body, contentType, headers);
        }

        /// <summary>
        /// Put
        /// </summary>
        /// <param name="url"></param>
        /// <param name="body"></param>
        /// <param name="contentType"></param>
        /// <returns></returns>
        public static string Put(string url, string body, string contentType = "application/json")
        {
            return HttpMethod("PUT", url, body, contentType);
        }

        /// <summary>
        /// Get
        /// </summary>
        /// <param name="url"></param>
        /// <param name="contentType"></param>
        /// <returns></returns>
        public static string Get(string url, string contentType = "application/json")
        {
            return HttpMethod("GET", url, "", contentType);
        }

        /// <summary>
        /// Get
        /// </summary>
        /// <param name="url"></param>
        /// <param name="headers"></param>
        /// <param name="contentType"></param>
        /// <returns></returns>
        public static string Get(string url, Dictionary<string, string> headers, string contentType = "application/json")
        {
            return HttpMethod("GET", url, null, contentType, headers);
        }

        /// <summary>
        /// Get獲取Image
        /// </summary>
        /// <param name="url"></param>
        /// <param name="contentType"></param>
        /// <returns></returns>
        public static Image Get_Image(string url, string contentType = "application/json")
        {        
            return HttpMethod((stream) => Image.FromStream(stream), "GET", url, "", contentType, null);
        }

        /// <summary>
        /// Get獲取byte[]
        /// </summary>
        /// <param name="url"></param>
        /// <param name="contentType"></param>
        /// <returns></returns>
        public static byte[] Get_byte(string url, string contentType = "application/json")
        {
            return HttpMethod((stream) =>
            {
                using (var ms = new MemoryStream())
                {
                    stream.CopyTo(ms);
                    using (stream)
                        return ms.ToArray();
                }
            } , "GET", url, "", contentType, null);
        }

        /// <summary>
        /// Delete操作
        /// </summary>
        /// <param name="url">url地址</param>
        /// <param name="body">內容</param>
        /// <param name="contentType">要求內容,默認application/json</param>
        /// <returns>返回值</returns>
        public static string Delete(string url, string body = "", string contentType = "application/json")
        {
            return HttpMethod("DELETE", url, body, contentType);
        }

        private static string HttpMethod(string method, string url, string body, string contentType = "application/json", Dictionary<string, string> headers = null)
        {
            return HttpMethod((stream) =>
            {
                using (StreamReader streamReader = new StreamReader(stream))
                {
                    return streamReader.ReadToEnd();
                }
            }, method, url, body, contentType, headers);
        }

        private static T HttpMethod<T>(Func<Stream, T> func, string method, string url, string body, string contentType = "application/json", Dictionary<string, string> headers = null)
        {
            if (string.IsNullOrEmpty(contentType)) contentType = "application/json";

            string responseContent = string.Empty;

            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
            httpWebRequest.Method = method;
            //httpWebRequest.Accept = "text/html, application/xhtml+xml, */*";
            httpWebRequest.Timeout = 600000;       // 10分鍾,10*60*1000=600000
            //httpWebRequest.KeepAlive = true;     // 獲取或設置一個值,該值指示是否與 Internet 資源建立持久性連接默認為true。
            httpWebRequest.ReadWriteTimeout = 600000; // 10分鍾,10*60*1000=600000
            httpWebRequest.ContentType = contentType; // 內容類型
            httpWebRequest.MaximumResponseHeadersLength = 40000;
            httpWebRequest.ContentLength = 0;

            if (headers != null)
            {
                FormatRequestHeaders(headers, httpWebRequest);
            }

            if (!string.IsNullOrEmpty(body))
            {
                byte[] btBodys = Encoding.UTF8.GetBytes(body);
                httpWebRequest.ContentLength = btBodys.Length;

                using (Stream writeStream = httpWebRequest.GetRequestStream())
                {
                    writeStream.Write(btBodys, 0, btBodys.Length);
                    writeStream.Flush();
                }
            }

            T t;
            using (HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse())
            {
                using (Stream stream = httpWebResponse.GetResponseStream())
                {
                    t = func(stream);
                }
            }

            return t;
        }

        /// <summary>
        /// 格式化請求頭信息
        /// </summary>
        /// <param name="headers"></param>
        /// <param name="request"></param>
        private static void FormatRequestHeaders(Dictionary<string, string> headers, HttpWebRequest request)
        {
            foreach (var hd in headers)
            {
                //因為HttpWebRequest中很多標准標頭都被封裝成只能通過屬性設置,添加的話會拋出異常
                switch (hd.Key.ToLower())
                {
                    case "connection":
                        request.KeepAlive = false;
                        break;
                    case "content-type":
                        request.ContentType = hd.Value;
                        break;
                    case "transfer-enconding":
                        request.TransferEncoding = hd.Value;
                        break;
                    default:
                        request.Headers.Add(hd.Key, hd.Value);
                        break;
                }
            }
        }
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM