C# HttpWebRequest 上传文件 (调用ArcGIS Rest API上传SOE文件)

2023-11-06 00:30

本文主要是介绍C# HttpWebRequest 上传文件 (调用ArcGIS Rest API上传SOE文件),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

缘起

想做一个SOE自动上传的小工具,查了查相关的ArcGIS Rest API,使用C#中的HttpWebRequet实现,k看GitHub上别人用Python实现的很简单,自己用C#搞了一天了没搞明白,记录一下采坑的过程。

相关资料

  1. ArcGIS Rest API Upload SOE:传送门
  2. C# Upload File:参考链接1、参考链接2、
  3. HttpClient实现方法:参考链接

PostMan测试

使用PostMan测试Form-data,参考链接
在这里插入图片描述

代码实现

  • HttpWebRequest

    private bool UploadSoe(string userName, string password, string soeFilePath, string ip = "localhost", string port = "6080")
    {bool bIsSuccess = false;//构造请求参数string token = GetToken(userName, password, ip, port);string boundary = CreateFormDataBoundary();byte[] postDataBytes = null;using (var postStream = new MemoryStream()){//写入表单参数string formDataTemplate = "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}\r\n";string fromData1 = string.Format(formDataTemplate, boundary, "f", "json");var dataFormdataBytes1 = Encoding.UTF8.GetBytes(fromData1);string formData2 = string.Format(formDataTemplate, boundary, "token", token);var dataFormdataBytes2 = Encoding.UTF8.GetBytes(formData2);//写入文件头部信息string fileFormdataTemplate = "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n";string soeFileName = System.IO.Path.GetFileName(soeFilePath);string fileHeader = string.Format(fileFormdataTemplate, boundary, "itemFile", soeFileName, "application/octet-stream");byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(fileHeader);//写入文件流byte[] fileBytes = null;using (FileStream fs = new FileStream(soeFilePath, FileMode.Open)){fileBytes = new byte[fs.Length];fs.Read(fileBytes, 0, fileBytes.Length);fs.Close();}//写入结尾string sEndBoundary = "\r\n--" + boundary + "--\r\n";var endBoundaryBytes = Encoding.UTF8.GetBytes(sEndBoundary);postStream.Write(dataFormdataBytes1, 0, dataFormdataBytes1.Length);postStream.Write(dataFormdataBytes2, 0, dataFormdataBytes2.Length);postStream.Write(headerbytes, 0, headerbytes.Length);postStream.Write(fileBytes, 0, fileBytes.Length);postStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);postStream.Position = 0;postDataBytes = new byte[postStream.Length];postStream.Read(postDataBytes, 0, postDataBytes.Length);postStream.Close(); }//创建Httphelper对象HttpHelper http = new HttpHelper();//创建Httphelper参数对象HttpItem item = new HttpItem(){URL = string.Format("http://{0}:{1}/arcgis/admin/uploads/upload", ip, port),Method = "POST",ContentType = string.Format("multipart/form-data; boundary={0}", boundary),PostDataType = Sys.PostDataType.Byte,PostdataByte = postDataBytes};//请求的返回值对象HttpResult result = http.GetHtml(item);if (result.StatusCode == System.Net.HttpStatusCode.OK){string html = result.Html;var jsonObj = JsonHelper.GetDynamicObjFromString(html);if (jsonObj.status.ToString() == "success"){bIsSuccess = true;}}return bIsSuccess;
    }private static string CreateFormDataBoundary()
    {return "----" + DateTime.Now.Ticks.ToString("x");
    }private string GetToken(string userName, string password, string ip = "localhost", string port = "6080")
    {//创建Httphelper对象HttpHelper http = new HttpHelper();//创建Httphelper参数对象HttpItem item = new HttpItem(){URL = string.Format("http://{0}:{1}/arcgis/admin/generateToken", ip, port),//URL     必需项    Method = "post",//URL     可选项 默认为Get   ContentType = "application/x-www-form-urlencoded",//返回类型    可选项有默认值Postdata = string.Format("username={0}&password={1}&client=requestip&expiration=90&f=json", userName, password),//Post要发送的数据};//请求的返回值对象HttpResult result = http.GetHtml(item);//从苏飞论坛或者Github获取,也可以自己用HttpWebRequest//获取请请求的Htmlstring html = result.Html;//获取请求的Cookievar jsonObj = JsonHelper.GetDynamicObjFromString(html);var token = jsonObj.token;return token.ToString();
    }
    
  • HttpClient

    private async void UploadSoe1(string userName, string password, string soeFilePath, string ip = "localhost", string port = "6080")
    {string token = GetToken(userName, password, ip, port);string soeFileName = Path.GetFileName(soeFilePath);using (FileStream stream = new FileStream(soeFilePath, FileMode.Open))using (HttpClient client = new HttpClient()){MultipartFormDataContent content = new MultipartFormDataContent();content.Add(new StringContent("pjson"), "f");content.Add(new StringContent(token), "token");content.Add(new StreamContent(stream){Headers ={ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream")}}, "itemFile", soeFileName);string url = string.Format("http://{0}:{1}/arcgis/admin/uploads/upload", ip, port);var response = await client.PostAsync(url, content);string resultContent = await response.Content.ReadAsStringAsync();}}
    

采坑小记

使用HttpWebRequest时需要自行构造body,这块相比HttpClient麻烦一点,这块要注意构造请求体是字符串的顺序,依次往requestStream中写入

  1. 构造boundary信息

    private static string CreateFormDataBoundary()
    {return "----" + DateTime.Now.Ticks.ToString("x");
    }
    
  2. 构造请求参数的相关信息

    string formDataTemplate = "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}\r\n";
    string fromData1 = string.Format(formDataTemplate, boundary, "f", "json");
    var dataFormdataBytes1 = Encoding.UTF8.GetBytes(fromData1);
    
  3. 构造上传文件的相关信息

    string fileFormdataTemplate = "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n";
    string soeFileName = System.IO.Path.GetFileName(soeFilePath);
    string fileHeader = string.Format(fileFormdataTemplate, boundary, "itemFile", soeFileName, "application/octet-stream");	
    byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(fileHeader);
    
  4. 添加换行

    byte[] bytes = Encoding.UTF8.GetBytes("\r\n");
    
  5. 添加结尾信息

    string sEndBoundary = "--" + boundary + "--\r\n";
    var endBoundaryBytes = Encoding.UTF8.GetBytes(sEndBoundary);
    

最后依次写入:

  Stream requestStream = request.GetRequestStream();requestStream.Write(dataFormdataBytes1, 0, dataFormdataBytes1.Length);requestStream.Write(dataFormdataBytes2, 0, dataFormdataBytes2.Length);//这块我有两个参数,没有封装函数,直接重复代码写了两遍requestStream.Write(headerbytes, 0, headerbytes.Length);requestStream.Write(fileBytes, 0, fileBytes.Length);byte[] bytes = Encoding.UTF8.GetBytes("\r\n");requestStream.Write(bytes, 0, bytes.Length);requestStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);

总结

如果对.Net Framework的版本没有要求的话(可以使用4.5及以上版本)建议使用HttpClient实现,毕竟HTTPWebRequest是很久之前的类,调用起来构造比较麻烦。

这篇关于C# HttpWebRequest 上传文件 (调用ArcGIS Rest API上传SOE文件)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/353427

相关文章

C# 比较两个list 之间元素差异的常用方法

《C#比较两个list之间元素差异的常用方法》:本文主要介绍C#比较两个list之间元素差异,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. 使用Except方法2. 使用Except的逆操作3. 使用LINQ的Join,GroupJoin

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

Python中Tensorflow无法调用GPU问题的解决方法

《Python中Tensorflow无法调用GPU问题的解决方法》文章详解如何解决TensorFlow在Windows无法识别GPU的问题,需降级至2.10版本,安装匹配CUDA11.2和cuDNN... 当用以下代码查看GPU数量时,gpuspython返回的是一个空列表,说明tensorflow没有找到

python如何调用java的jar包

《python如何调用java的jar包》这篇文章主要为大家详细介绍了python如何调用java的jar包,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以参考一下... 目录一、安装包二、使用步骤三、代码演示四、自己写一个jar包五、打包步骤六、方法补充一、安装包pip3 install

HTML5 getUserMedia API网页录音实现指南示例小结

《HTML5getUserMediaAPI网页录音实现指南示例小结》本教程将指导你如何利用这一API,结合WebAudioAPI,实现网页录音功能,从获取音频流到处理和保存录音,整个过程将逐步... 目录1. html5 getUserMedia API简介1.1 API概念与历史1.2 功能与优势1.3

C#如何去掉文件夹或文件名非法字符

《C#如何去掉文件夹或文件名非法字符》:本文主要介绍C#如何去掉文件夹或文件名非法字符的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#去掉文件夹或文件名非法字符net类库提供了非法字符的数组这里还有个小窍门总结C#去掉文件夹或文件名非法字符实现有输入字

C#之List集合去重复对象的实现方法

《C#之List集合去重复对象的实现方法》:本文主要介绍C#之List集合去重复对象的实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C# List集合去重复对象方法1、测试数据2、测试数据3、知识点补充总结C# List集合去重复对象方法1、测试数据

C#实现将Office文档(Word/Excel/PDF/PPT)转为Markdown格式

《C#实现将Office文档(Word/Excel/PDF/PPT)转为Markdown格式》Markdown凭借简洁的语法、优良的可读性,以及对版本控制系统的高度兼容性,逐渐成为最受欢迎的文档格式... 目录为什么要将文档转换为 Markdown 格式使用工具将 Word 文档转换为 Markdown(.

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET

C#代码实现解析WTGPS和BD数据

《C#代码实现解析WTGPS和BD数据》在现代的导航与定位应用中,准确解析GPS和北斗(BD)等卫星定位数据至关重要,本文将使用C#语言实现解析WTGPS和BD数据,需要的可以了解下... 目录一、代码结构概览1. 核心解析方法2. 位置信息解析3. 经纬度转换方法4. 日期和时间戳解析5. 辅助方法二、L