通过HTTP请求WEBAPI的方式

Posted Henry

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过HTTP请求WEBAPI的方式相关的知识,希望对你有一定的参考价值。

  平时工作中长期需要用到通过HTTP调用API进行数据获取以及文件上传下载(C#,JAVA...都会用到)。这里获取的是包括网页的所有信息。如果单纯需要某些数据内容。可以自己构造函数甄别抠除出来!一般的做法是根据源码的格式,用正则来过滤出你需要的内容部分。

  C#中的调用:

    方式一:webclient和httpclient

    方式二:WebRequest和webresponse

    方式三:通过js 直接访问api接口,页面通过jquery调用

    方式四:WebBrowser

1.webclient和httpclient

  实例①

#region webclient应用
        #region Controllers
        MyImageServerEntities db = new MyImageServerEntities();
        public ActionResult Index()
        {
            return View();
        }
        public ActionResult FileUpload()
        {
            HttpPostedFileBase file = Request.Files["fileUp"];
            string fileName = Path.GetFileName(file.FileName);
            string fileExt = Path.GetExtension(fileName);
            if (fileExt == ".jpg")
            {
                var list = db.ImageServerInfo.Where<ImageServerInfo>(u => u.FlgUsable == true).ToList();//找出可用的图片服务器.
                int count = list.Count();
                Random random = new Random();
                int r = random.Next();
                int i = r % count;
                string serverUrl = list[i].ServerUrl;
                int serverId = list[i].ServerId;
                string url = "http://" + serverUrl + "/FileUp.ashx?serverId=" + serverId + "&fileExt=" + fileExt;
                WebClient webClient = new WebClient();
                webClient.UploadData(url, StreamToBytes(file.InputStream));

            }
            return Content("ok");

        }
        public ActionResult ShowImage()
        {
            var list = db.ImageServerInfo.Where<ImageServerInfo>(c => c.FlgUsable == true).ToList();
            ViewData["imageServerList"] = list;
            return View();
        }
        private byte[] StreamToBytes(Stream stream)
        {
            byte[] buffer = new byte[stream.Length];
            stream.Read(buffer, 0, buffer.Length);
            stream.Seek(0, SeekOrigin.Begin);
            return buffer;
        }
        #endregion

        #region Model
        context.Response.ContentType = "text/plain"; 
        int serverId = int.Parse(context.Request["serverId"]);
        string fileExt = context.Request["fileExt"];
        string dir = "/ImagePath/" + DateTime.Now.Year + "/" + DateTime.Now.Month + "/" + DateTime.Now.Day + "/";
        Directory.CreateDirectory(Path.GetDirectoryName(context.Request.MapPath(dir))); 
        string newfileName = Guid.NewGuid().ToString();
        string fullDir = dir + newfileName + fileExt;
        using (FileStream fileStream = File.Open(context.Request.MapPath(fullDir), FileMode.OpenOrCreate)) 
        { 
            context.Request.InputStream.CopyTo(fileStream);     
            MyImageServerEntities db = new MyImageServerEntities();
            ImageInfo imageInfo = new ImageInfo();
            imageInfo.ImageName = fullDir;     
            imageInfo.ImageServerId = serverId;     
            db.ImageInfo.Add(imageInfo);    
            db.SaveChanges(); 
         }
#endregion
#endregion

#region httpclient
创建并初始化对象:
    client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

读集合:
    HttpResponseMessage response = client.GetAsync(url).Result;
var userList = response.Content.ReadAsAsync<IEnumerable<数据类型>>().Result;

根据编号读对象
    HttpResponseMessage response1 = client.GetAsync(url).Result;
    var userInfo = response1.Content.ReadAsAsync<数据类型>().Result;

增加:
    HttpResponseMessage response = client.PostAsJsonAsync("api/userinfo", userInfo).Result;
使用response.IsSuccessStatusCode判断是否成功
使用response.Content.ToString()获取返回值

修改:
     HttpResponseMessage response = client.PutAsJsonAsync("api/userinfo/" + userInfo.UserId, userInfo).Result;
使用response.IsSuccessStatusCode判断是否成功
使用response.Content.ToString()获取返回值

删除:
    HttpResponseMessage response = client.DeleteAsync("api/userinfo/" + uid).Result;
使用response.IsSuccessStatusCode判断是否成功
使用response.Content.ToString()获取返回值
        #endregion
View Code

  实例②

WebClient获取网页数据:
            //using System.IO;
            try
            {
                WebClient webClient = new WebClient();
                webClient.Credentials = CredentialCache.DefaultCredentials;//获取或设置用于向Internet资源的请求进行身份验证的网络凭据
                Byte[] pageData = webClient.DownloadData("http://www.360doc.com/content/11/0427/03/1947337_112596569.shtml");
                //string pageHtml = Encoding.Default.GetString(pageData);  //如果获取网站页面采用的是GB2312,则使用这句       
                string pageHtml = Encoding.UTF8.GetString(pageData); //如果获取网站页面采用的是UTF-8,则使用这句
                using (StreamWriter sw = new StreamWriter("e:\\\\ouput.txt"))//将获取的内容写入文本
                {
                    htm = sw.ToString();//测试StreamWriter流的输出状态,非必须
                    sw.Write(pageHtml);
                }
            }
            catch (WebException webEx)
            {
                Console.W
            }

如果为了实际项目的效率考虑,需要考虑在函数中分配一个内存区域。大概写法如下:
//MemoryStream是一个支持储存区为内存的流。
 byte[] buffer = new byte[1024];
 using (MemoryStream memory = new MemoryStream())
    {
    int index = 1, sum = 0;
    while (index * sum < 100 * 1024)
    {
       index = reader.Read(buffer, 0, 1024);
       if (index > 0)
       {
           memory.Write(buffer, 0, index);
            sum += index;
       }
    }
    //网页通常使用utf-8或gb2412进行编码
    Encoding.GetEncoding("gb2312").GetString(memory.ToArray());
    if (string.IsNullOrEmpty(html))
    {
        return html;
    }
    else
    {
        Regex re = new Regex(@"charset=(? charset[/s/S]*?)[ |\']");
        Match m = re.Match(html.ToLower());
        encoding = m.Groups[charset].ToString();
    }
    if (string.IsNullOrEmpty(encoding) || string.Equals(encoding.ToLower(), "gb2312"))
    {
       return html;
    }
}
View Code

  实例③

使用WebClient进行文件下载,这里使用了Task异步方式,也可以改为普通方法或静态方法:
/// <summary>
/// 下载文件
/// </summary>
/// <param name="fileUrl">文件地址</param>
/// <param name="filePath">文件的本地路径</param>
/// <returns>文件在本地的存储路径</returns>
private Task GetFileLocalPath(string fileUrl, string filePath)
{
    return Task.Run(() =>
    {
        try
        {
            using (var mc = new WebClient())
            {
                mc.DownloadFile(new Uri(fileUrl), filePath);
            }
        }
        catch (Exception ex)
        {
            LogHelper.WriteErrorLog("下载文件时出现异常。", ex);
        }
    });
}

/// <summary>
/// 下载文件
/// </summary>
/// <param name="fileUrl">文件地址</param>
/// <param name="filePath">文件的本地路径</param>
/// <returns>文件在本地的存储路径</returns>
private Task DownloadFile(string fileUrl, string filePath)
{
    return Task.Run(() =>
    {
        try
        {
            using (var webClient = new WebClient())
            {
                var netStream = webClient.OpenRead(fileUrl);
                if (netStream != null)
                {
                    FileStream fstr = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write);
                    byte[] readbyte = new byte[102400];
                    int realReadLen = netStream.Read(readbyte, 0, readbyte.Length);
                    while (realReadLen > 0)
                    {
                        fstr.Write(readbyte, 0, realReadLen);
                        realReadLen = netStream.Read(readbyte, 0, readbyte.Length);
                        Thread.Sleep(10);
                    }
                    netStream.Dispose();
                    fstr.Flush();
                    fstr.Close();
                }
            }
        }
        catch (Exception ex)
        {
            LogHelper.WriteErrorLog("下载文件时出现异常。", ex);
        }
    });
}

HttpClient,这个类提供的都是异步方法,下面包含了POST、GET、PUT、DELETE四个方法,还有一个SEND方法稍加改动即可实现:
public static async void AsyncPost(string url, string body, Action<RequestResult> callback, int timeoutSeconds = 10)
{
    var requestResult = new RequestResult();
    if (!IsConnectedInternet())
    {
        requestResult.Message = "网络连接错误,请稍后再试。";
        callback?.Invoke(requestResult);
        return;
    }

    try
    {
        using (var client = new HttpClient())
        {
            client.DefaultRequestHeaders.Add("authorization", "LJQfL1A2oeP2fuEiOHo6");
            client.Timeout = new TimeSpan(0, 0, timeoutSeconds);
            //byte[] requestBody = Encoding.UTF8.GetBytes(body);
            HttpContent content = new StringContent(body);
            content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            var response = await client.PostAsync(url, content);
            //确保HTTP成功状态值
            response.EnsureSuccessStatusCode();
            //await异步读取最后的JSON
            await response.Content.ReadAsStringAsync().ContinueWith(t =>
            {
                if (t.IsCompleted)
                {
                    requestResult.IsSuccess = true;
                    requestResult.Result = t.Result;
                    callback?.Invoke(requestResult);
                }
            });
        }
    }
    catch (Exception e)
    {
        if (e.InnerException != null)
            requestResult.Message = e.InnerException.Message;
        else if (e.Message.Contains("已取消一个任务"))
            requestResult.Message = "连接服务器超时,请重试";
        else if (e.Message.Contains("404"))
            requestResult.Message = "连接服务器404,请重试";
        else
            requestResult.Message = e.Message;
        callback?.Invoke(requestResult);
    }
}

public static async void AsyncGet(string url, Action<RequestResult> callback, int timeoutSeconds = 10)
{
    var requestResult = new RequestResult();
    if (!IsConnectedInternet())
    {
        requestResult.Message = "网络连接错误,请稍后再试。";
        callback?.Invoke(requestResult);
        return;
    }

    try
    {
        using (var client = new HttpClient())
        {
            client.DefaultRequestHeaders.Add("authorization", "LJQfL1A2oeP2fuEiOHo6");
            client.Timeout = new TimeSpan(0, 0, timeoutSeconds);
            var response = await client.GetAsync(url);
            //确保HTTP成功状态值
            response.EnsureSuccessStatusCode();
            //await异步读取最后的JSON
            await response.Content.ReadAsStringAsync().ContinueWith(t =>
            {
                if (t.IsCompleted)
                {
                    requestResult.IsSuccess = true;
                    requestResult.Result = t.Result;
                    callback?.Invoke(requestResult);
                }
            });
        }
    }
    catch (Exception e)
    {
        if (e.InnerException != null)
            requestResult.Message = e.InnerException.Message;
        else if (e.Message.Contains("已取消一个任务"))
            requestResult.Message = "连接服务器超时,请重试";
        else if (e.Message.Contains("404"))
            requestResult.Message = "连接服务器404,请重试";
        else
            requestResult.Message = e.Message;
        callback?.Invoke(requestResult);
    }
}

public static async void AsyncPut(string url, string body, Action<RequestResult> callback, int timeoutSeconds = 10)
{
    var requestResult = new RequestResult();
    if (!IsConnectedInternet())
    {
        requestResult.Message = "网络连接错误,请稍后再试。";
        callback?.Invoke(requestResult);
        return;
    }

    try
    {
        using (var client = new HttpClient())
        {
            client.DefaultRequestHeaders.Add("authorization", "LJQfL1A2oeP2fuEiOHo6");
            client.Timeout = new TimeSpan(0, 0, timeoutSeconds);
            HttpContent content = new StringContent(body);
            content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            var response = await client.PutAsync(url, content);
            //确保HTTP成功状态值
            response.EnsureSuccessStatusCode();
            //await异步读取最后的JSON
            await response.Content.ReadAsStringAsync().ContinueWith(t =>
            {
                if (t.IsCompleted)
                {
                    requestResult.IsSuccess = true;
                    requestResult.Result = t.Result;
                    callback?.Invoke(requestResult);
                }
            });
        }
    }
    catch (Exception e)
    {
        if (e.InnerException != null)
            requestResult.Message = e.InnerException.Message;
        else if (e.Message.Contains("已取消一个任务"))
            requestResult.Message = "连接服务器超时,请重试";
        else if (e.Message.Contains("404"))
            requestResult.Message = "连接服务器404,请重试";
        else
            requestResult.Message = e.Message;
        callback?.Invoke(requestResult);
    }
}

public static async void AsyncDelete(string url, Action<RequestResult> callback, int timeoutSeconds = 10)
{
    var requestResult = new RequestResult();
    if (!IsConnectedInternet())
    {
        requestResult.Message = "网络连接错误,请稍后再试。";
        callback?.Invoke(requestResult);
        return;
    }

    try
    {
        using (var client = new HttpClient())
        {
            client.DefaultRequestHeaders.Add("authorization", "LJQfL1A2oeP2fuEiOHo6");
            client.Timeout = new TimeSpan(0, 0, timeoutSeconds);
            var response = await client.DeleteAsync(url);
            //确保HTTP成功状态值
            response.EnsureSuccessStatusCode();
            //await异步读取最后的JSON
            await response.Content.ReadAsStringAsync().ContinueWith(t =>
            {
                if (t.IsCompleted)
                {
                    requestResult.IsSuccess = true;
                    requestResult.Result = t.Result;
                    callback?.Invoke(requestResult);
                }
            });
        }
    }
    catch (Exception e)
    {
        if (e.InnerException != null)
            requestResult.Message = e.InnerException.Message;
        else if (e.Message.Contains("已取消一个任务"))
            requestResult.Message = "连接服务器超时,请重试";
        else if (e.Message.Contains("404"))
            requestResult.Message = "连接服务器404,请重试";
        else
            requestResult.Message = e.Message;
        callback?.Invoke(requestResult);
    }
}

上面使用到的RequestResult类:
public class RequestResult : IDisposable
{
    public bool IsSuccess { get; set; }

    public string Result { get; set; }

    public string Message { get; set; }

    public RequestResult(bool isSuccess = false, string result = "", string message = "")
    {
        IsSuccess = isSuccess;
        Result = result;
        Message = message;
    }

    ~RequestResult()
    {
        Dispose();
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);//不需要再调用本对象的Finalize方法
    }

    protected virtual void Dispose(Boolean disposing)
    {
        if (disposing)
        {
            //--- 清理托管资源 ---//
        }

        //--- 清理非托管资源 ---//
    }
}
View Code

2.WebRequest和webresponse

  实例①

   public void GetHtml()
        {
            var url = "http://www.360doc.com/content/11/0427/03/1947337_112596569.shtml";
            string strBuff = "";//定义文本字符串,用来保存下载的html
            int byteRead = 0; 
            
            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
            HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
            //若成功取得网页的内容,则以System.IO.Stream形式返回,若失败则产生ProtoclViolationException错 误。在此正确的做法应将以下的代码放到一个try块中处理。这里简单处理 
            Stream reader = webResponse.GetResponseStream();
            ///返回的内容是Stream形式的,所以可以利用StreamReader类获取GetResponseStream的内容,并以StreamReader类的Read方法依次读取网页源程序代码每一行的内容,直至行尾(读取的编码格式:UTF8)
            StreamReader respStreamReader = new StreamReader(reader,Encoding.UTF8);
 
            ///分段,分批次获取网页源码
            char[] cbuffer = new char[1024];
            byteRead = respStreamReader.Read(cbuffer,0,256);
 
            while (byteRead != 0)
            {
                string strResp = new string(char,0,byteRead);
                strBuff = strBuff + strResp;
                byteRead = respStreamReader.Read(cbuffer,0,256);
            }
            using (StreamWriter sw = new StreamWriter("e:\\\\ouput.txt"))//将获取的内容写入文本
            {
                htm = sw.ToString();//测试StreamWriter流的输出状态,非必须
                sw.Write(strBuff);
            }
        }
View Code

  实例②

WebRequest的方式(该方式是post请求的时候传入json字符串转换成流的形式,无需再将json转换成需要的实体对象了),所以这种方式只需写一个公共的方法,每次调用的时候传入地址和参数即可
公共方法如下:
public class WebRequestHelper
    {
        public static string GetRequest(string url)
        {
            string responseStr = string.Empty;


            WebRequest request = WebRequest.Create(url);
            request.Method = "Get";
            var response = request.GetResponse();
            Stream ReceiveStream = response.GetResponseStream();
            using (StreamReader stream = new StreamReader(ReceiveStream, Encoding.UTF8))
            {
                responseStr = stream.ReadToEnd();
            }

            return responseStr;
        }

        public static string PostRequest(string url, string postParameter)
        {
            string responseStr = string.Empty;

            WebRequest request = WebRequest.Create(url);
            request.Method = "Post";
            request.ContentType = "application/json";

            byte[] requestData = System.Text.Encoding.UTF8.GetBytes(postParameter);
            request.ContentLength = requestData.Length;

            Stream newStream = request.GetRequestStream();
            newStream.Write(requestData, 0, requestData.Length);
            newStream.Close();

            var response = request.GetResponse();
            Stream ReceiveStream = response.GetResponseStream();
            using (StreamReader stream = new StreamReader(ReceiveStream, Encoding.UTF8))
            {
                responseStr = stream.ReadToEnd();
            }

            return responseStr;
        }

        /// <summary>
        /// Http的 WebRequest的特定实现
        /// </summary>
        /// <param name="Url"></param>
        /// <param name="JSONData"></param>
        /// <returns></returns>
        public static string GetResponseData(string Url, string JSONData)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(JSONData);
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
            request.Method = "POST";
            request.ContentLength = bytes.Length;
            request.ContentType = "application/json";
            Stream reqstream = request.GetRequestStream();
            reqstream.Write(bytes, 0, bytes.Length);

            分布式技术 webapi

WebApi 登录身份验证

WebApi跨域

通过 HTTP 发送文件的最佳方式是啥?

postman 自动生成 curl 代码片段

postman 自动生成 curl 代码片段