• .Net C#向远程服务器Api上传文件


    Api服务代码一:

            /// <summary>
            /// 服务器接收接口
            /// </summary>
            [HttpPost]
            [Route("ReceiveFile")]
            public HttpResponseMessage ReceiveFile()
            {
                string result = string.Empty;
                ArrayList list = new ArrayList();
                try
                {
                    Stream postStream = HttpContext.Current.Request.InputStream;
                    byte[] b = new byte[postStream.Length];
    
                    string postFileName = DNTRequest.GetString("fileName");
                    if (string.IsNullOrEmpty(postFileName) && HttpContext.Current.Request["fileName"] != null)
                    {
                        postFileName = HttpContext.Current.Request["fileName"];
                    }
                    string fileExtension = Path.GetExtension(postFileName);
                    string dirName = "other";
                    if (!string.IsNullOrEmpty(fileExtension))
                    {
                        dirName = fileExtension.Substring(fileExtension.LastIndexOf(".") + 1);
                    }
                    string dir = "/_temp/file/" + dirName + "/" + DateTime.Now.ToString("yyyyMMdd") + "/";
                    string fileName = DateTime.Now.ToString("yyyyMMddHHmmss_ffff");
                    fileName += fileExtension;
                    string filePath = HttpContext.Current.Server.MapPath(dir);
                    string saveFilePath = Path.Combine(filePath, fileName);
                    string dirPath = dir + fileName;
                    list.Add(dirPath);
    
                    if (!Directory.Exists(filePath))
                    {
                        Directory.CreateDirectory(filePath);
                    }
    
                    FileStream fs = new FileStream(saveFilePath, FileMode.Create);
                    byte[] new_b = new byte[1024];
                    const int rbuffer = 1024;
    
                    while (postStream.Read(new_b, 0, rbuffer) != 0)
                    {
                        fs.Write(new_b, 0, rbuffer);
                    }
                    postStream.Close();
                    fs.Close();
                    fs.Dispose();
    
                    if (list.Count > 0)
                    {
                        result = DNTRequest.GetResultJson(true, "success", string.Join(",", list.ToArray()));
                    }
                }
                catch (Exception ex)
                {
                    result = DNTRequest.GetResultJson(false, ex.Message, null);
                }
                HttpResponseMessage responseMessage = new HttpResponseMessage { Content = new StringContent(result, Encoding.GetEncoding("UTF-8"), "text/plain") };
                return responseMessage;
            }

    Api服务代码二:

            [HttpPost]
            [Route("ReceiveFileTest")]
            public HttpResponseMessage ReceiveFileTest()
            {
                string result = string.Empty;
                var request = HttpContext.Current.Request;
                try
                {
                    if (request.Files.Count > 0)
                    {
                        var fileNameList = new List<string>();
                        string dirName = "other";
                        foreach (string f in request.Files)
                        {
                            var file = request.Files[f];
    
                            string fileExtension = Path.GetExtension(file.FileName).ToLower();
                            string fileName = DateTime.Now.ToString("yyyyMMddHHmmss_ffff");
                            fileName += fileExtension;
                            if (!string.IsNullOrEmpty(fileExtension))
                            {
                                dirName = fileExtension.Substring(fileExtension.LastIndexOf(".") + 1);
                            }
                            string dir = "/_temp/file/" + dirName + "/" + DateTime.Now.ToString("yyyyMMdd") + "/";
                            string filePath = HttpContext.Current.Server.MapPath(dir);
                            if (!Directory.Exists(filePath))
                            {
                                Directory.CreateDirectory(filePath);
                            }
                            string fileSavePath = Path.Combine(filePath, fileName);
    
                            Stream postStream = file.InputStream;
                            //
                            FileStream fs = new FileStream(fileSavePath, FileMode.Create);
                            byte[] new_b = new byte[1024];
                            const int rbuffer = 1024;
    
                            while (postStream.Read(new_b, 0, rbuffer) != 0)
                            {
                                fs.Write(new_b, 0, rbuffer);
                            }
                            postStream.Close();
                            fs.Close();
                            fs.Dispose();
    
                            string dirPath = dir + fileName;
                            fileNameList.Add(dirPath);
                            fileNameList.Add(fileName);
                        }
    
                        result = DNTRequest.GetResultJson(true, string.Format("{0}:{1}", HttpStatusCode.OK, string.Join(",", fileNameList.ToArray())), null);
                    }
                    else
                    {
                        result = DNTRequest.GetResultJson(false, "请选择上传的文件", null);
                    }
                }
                catch (Exception ex)
                {
                    result = DNTRequest.GetResultJson(false, ex.Message, null);
                }
                HttpResponseMessage responseMessage = new HttpResponseMessage { Content = new StringContent(result, Encoding.GetEncoding("UTF-8"), "text/plain") };
                return responseMessage;
            }

    Ajax提交file代码,调用Api代码一的Script:

    此方法后端Api代码一中始终获取不到文件名,所以我在Ajax的url中加了?fileName=fileObj.name,这样调试能走通。为什么Ajax提交时不能获取到文件名,我还在研究。

    <script>
    
            $("#inpSubmit").click(function () {
                //var fileObj = new FormData($("#importModel")[0]);
                var fileObj = document.getElementById("inpFileControl").files[0];
                if (typeof (fileObj) == "undefined" || fileObj.size <= 0) {
                    alert("请选择文件");
                    return;
                }
                //console.log(fileObj);
    
                var formFile = new FormData();
                formFile.append("fileName", fileObj.name);
                formFile.append("file", fileObj);
                //console.log(JSON.stringify(formFile));
    
                //var paramters = {};
                //paramters.timestamp = new Date().getTime();
                //paramters.fileName = fileObj.name;
                //paramters.file = fileObj;
                //console.log(JSON.stringify(paramters));
    
                $.ajax({
                    type: "post",
                    url: "http://localhost:19420/Api/ReceiveFile?fileName=" + fileObj.name,
                    dataType: "json",
                    //contentType: false,
                    processData: false,//用于对data参数进行序列化处理,默认值是true。默认情况下发送的数据将被转换为对象,如果不希望把File转换,需要设置为false
                    cache: false,
                    data: fileObj,
                    success: function (json) {
                        if (json.result) {
                            $("#inpFileUrl").val(json.data);
                            console.log(json.data);
                        }
                        else {
                            alert(json.msg);
                        }
                    },
                    error: function (ret) {
                        console.log(ret.responseText);
                    }
                });
                return false;
            });
        </script>
    

    Ajax提交file代码,调用Api代码一的Html:

    <form>
        <fieldset>
            <legend>Ajax提交到远程服务器Api</legend>
            <div class="form-group">
                <label class="col-sm-2 control-label" for="ds_host">选择文件</label>
                <div class="col-sm-4">
                    <input class="form-control" id="inpFileUrl" name="inpFileUrl" type="text" placeholder="上传后返回地址" />
                </div>
                <div class="col-sm-4">
                    <input type="file" id="inpFileControl" name="file" />
                </div>
                <div class="col-sm-2">
                    <input id="inpSubmit" name="inpSubmit" type="button" value="提交" />
                </div>
            </div>
        </fieldset>
    </form>

    Form表单提交Post到远程Api代码二中,这个很顺利。下边是Html

    <form action="http://localhost:19420/Api/ReceiveFileTest" method="post" enctype="multipart/form-data">
        <fieldset>
            <legend>Form表单提交到远程服务器Api</legend>
            <div class="form-group">
                <label class="col-sm-2 control-label" for="ds_host">选择文件</label>
                <div class="col-sm-4">
                    <input class="form-control" id="inpFileUrl2" name="inpFileUrl2" type="text" placeholder="上传后返回地址" />
                </div>
                <div class="col-sm-4">
                    <input type="file" name="file" />
                </div>
                <div class="col-sm-2">
                    <input type="submit" value="提交" />
                </div>
            </div>
        </fieldset>
    </form>

    Api服务部署时需要考虑到客户端提交file时有跨域问题,快捷方法是在IIS中设置Access-Control-Allow-Origin:*,但这样做有安全问题。

    网站上传文件大小默认4M,所以网站配置文件中需要设置,如下:

      <system.web>
        <httpRuntime maxRequestLength="409600" />
      </system.web>

    服务器IIS上传文件大小也有限制,也要做设置,如下:

      <system.webServer>
        <security>
          <requestFiltering>
            <!--2G/2072576000|500M/518144000-->
            <requestLimits maxAllowedContentLength="518144000"/>
          </requestFiltering>
        </security>
      </system.webServer>

    以上是我近2天的研究成果,不算完善还需要改进。

    Api中使用了三方框架RestSharp,请在解决方案中找NuGet添加。

    外部操作类用到的方法有,一:

            /// <summary>
            /// 拼装JSON
            /// </summary>
            static public string GetResultJson(bool result, string msg, Object data)
            {
                string resultJson = string.Empty;
                Hashtable ht = new Hashtable();
                try
                {
                    ht.Add("result", result);
                    ht.Add("msg", msg);
                    ht.Add("data", data);
                }
                catch (Exception ex)
                {
                    ht.Add("result", false);
                    ht.Add("msg", ex.Message);
                }
                resultJson = Newtonsoft.Json.JsonConvert.SerializeObject(ht);
                return resultJson;
            }

     注意:Html代码中file控件需要有name=“file”属性,否则提交后Api获取不到file对象,如下。

    <input type="file" name="file" />

    第三种方法是form表单提交调用mvc的control,control在调用Api代码二,这个测试失败,能上传文件,但上传的文件不能打开是损坏的,正在想办法解决。

    下边是第三种方法的Html代码:

    <form action="/Test/UploadFileTest" method="post" enctype="multipart/form-data">
        <fieldset>
            <legend>Form表单提交到本地Control</legend>
            <div class="form-group">
                <label class="col-sm-2 control-label" for="ds_host">选择文件</label>
                <div class="col-sm-4">
                    <input class="form-control" id="inpFileUrl3" name="inpFileUrl3" type="text" placeholder="上传后返回地址" />
                </div>
                <div class="col-sm-4">
                    <input type="file" name="file" />
                </div>
                <div class="col-sm-2">
                    <input type="submit" value="提交" />
                </div>
            </div>
        </fieldset>
    </form>

    下边是第三种方法的Control代码:

            [HttpPost]
            public ActionResult UploadFileTest()
            {
                string result = string.Empty;
    
                string apiUrl = "http://localhost:19420/Api/ReceiveFileTest";
                string contentType = "application/octet-stream";
    
                var files = new List<string>();
                foreach (string f in Request.Files)
                {
                    var file = Request.Files[f];
                    var request = new RestRequest(Method.POST);
                    request.AlwaysMultipartFormData = true;
                    //request.AddParameter("fileName", file.FileName);
                    Stream postStream = file.InputStream;
                    byte[] b = new byte[postStream.Length];
                    request.AddFile("file", b, file.FileName, contentType);
    
                    var restClient = new RestClient { BaseUrl = new Uri(apiUrl) };
                    string res = string.Empty;
                    IRestResponse<Object> response = restClient.Execute<Object>(request);
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        res = response.Content;
                    }
                    else
                    {
                        res = string.Format("{0}:{1}", response.StatusCode, response.Content);
                    }
                    files.Add(res);
                }
                if (files.Count > 0) {
                    result = string.Join(",", files.ToArray());
                }
    
                return Json(result);
            }
  • 相关阅读:
    邮箱的第99封邮件,第1个Offer
    学校的多媒体网站也模仿Google改版了
    惠普:计算机在非洲大有可为(zz)
    PPLive是不错的东东
    Google增加反病毒功能
    开复给中国学生的第五封信 – 你有选择的权利(zz)
    Yahoo中国变脸?
    拟停止本Blog更新
    在FC4上装GT4.0
    Google CodeJam 中国编程挑战赛拉开帷幕
  • 原文地址:https://www.cnblogs.com/hofmann/p/10757268.html
Copyright © 2020-2023  润新知