无法从 http 请求中读取文件名 header

Not able to read the file name from the http request header

我无法读取文件名以及来自客户端的其他值。我正在使用 HttpWebRequest 将多部分数据发送到服务器。我的客户端代码如下所示:

public string upload(string file, string url)
    {
        HttpWebRequest requestToServer = (HttpWebRequest)
WebRequest.Create(url);


        // Define a boundary string
        string boundaryString = "----";

        // Turn off the buffering of data to be written, to prevent
        // OutOfMemoryException when sending data
        requestToServer.AllowWriteStreamBuffering = false;
        // Specify that request is a HTTP post
        requestToServer.Method = WebRequestMethods.Http.Post;
        // Specify that the content type is a multipart request
        requestToServer.ContentType
            = "multipart/form-data; boundary=" + boundaryString;
        // Turn off keep alive
        requestToServer.KeepAlive = false;


        ASCIIEncoding ascii = new ASCIIEncoding();
        string boundaryStringLine = "\r\n--" + boundaryString + "\r\n";
        byte[] boundaryStringLineBytes = ascii.GetBytes(boundaryStringLine);

        string lastBoundaryStringLine = "\r\n--" + boundaryString + "--\r\n";
        byte[] lastBoundaryStringLineBytes = ascii.GetBytes(lastBoundaryStringLine);

        NameValueCollection nvc = new NameValueCollection();
        nvc.Add("id", "TTR");


        // Get the byte array of the myFileDescription content disposition
        string myFileDescriptionContentDisposition = Java.Lang.String.Format(
            "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}",
            "myFileDescription",
            "A sample file description");
        byte[] myFileDescriptionContentDispositionBytes
            = ascii.GetBytes(myFileDescriptionContentDisposition);

        string fileUrl = file;
        // Get the byte array of the string part of the myFile content
        // disposition
        string myFileContentDisposition = Java.Lang.String.Format(
            "Content-Disposition: form-data;name=\"{0}\"; "
             + "filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n",
            "myFile", Path.GetFileName(fileUrl), Path.GetExtension(fileUrl));
        byte[] myFileContentDispositionBytes =
            ascii.GetBytes(myFileContentDisposition);

        var name = Path.GetFileName(fileUrl);

        FileInfo fileInfo = new FileInfo(fileUrl);

        // Calculate the total size of the HTTP request
        long totalRequestBodySize = boundaryStringLineBytes.Length * 2
            + lastBoundaryStringLineBytes.Length
            + myFileDescriptionContentDispositionBytes.Length
            + myFileContentDispositionBytes.Length
            + fileInfo.Length;
        // And indicate the value as the HTTP request content length
        requestToServer.ContentLength = totalRequestBodySize;

        string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
        // Write the http request body directly to the server
        using (Stream s = requestToServer.GetRequestStream())
        {
            //foreach (string key in nvc.Keys)
            //{
            //    s.Write(boundaryStringLineBytes, 0, boundaryStringLineBytes.Length);
            //    string formitem = string.Format(formdataTemplate, key, nvc[key]);
            //    byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
            //    s.Write(formitembytes, 0, formitembytes.Length);

            //}
            // Send the file description content disposition over to the server
            s.Write(boundaryStringLineBytes, 0, boundaryStringLineBytes.Length);
            s.Write(myFileDescriptionContentDispositionBytes, 0,
                myFileDescriptionContentDispositionBytes.Length);

            // Send the file content disposition over to the server
            s.Write(boundaryStringLineBytes, 0, boundaryStringLineBytes.Length);
            s.Write(myFileContentDispositionBytes, 0,
                myFileContentDispositionBytes.Length);

            // Send the file binaries over to the server, in 1024 bytes chunk
            FileStream fileStream = new FileStream(fileUrl, FileMode.Open,
                FileAccess.Read);
            byte[] buffer = new byte[1024];
            int bytesRead = 0;
            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
            {
                s.Write(buffer, 0, bytesRead);
            } // end while

            fileStream.Close();

            // Send the last part of the HTTP request body
            s.Write(lastBoundaryStringLineBytes, 0, lastBoundaryStringLineBytes.Length);

            WebResponse response = requestToServer.GetResponse();

            StreamReader responseReader = new StreamReader(response.GetResponseStream());
            string replyFromServer = responseReader.ReadToEnd();

            return replyFromServer;
        }
    }

在客户端写入的 content-disposition 值未在服务器端检索。在服务器端,文件名被读取为“{0}”,随后其他值被读取为“{1}”和“{2}”。

我的服务器端代码如下所示:

 public async Task<HttpResponseMessage> UploadFile()
    {
        if (!Request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
        }

        string root = HttpContext.Current.Server.MapPath("~/App_Data");
        var provider = new MultipartFormDataStreamProvider(root);

        var httpRequest = HttpContext.Current.Request;


        var id = httpRequest.Form["{0}"];
        var id2 = httpRequest.Form[0];

        var s = id;
        var l = id2;

        // Read the form data.
        await Request.Content.ReadAsMultipartAsync(provider);

        // This illustrates how to get the file names.
        foreach (MultipartFileData file in provider.FileData)
        {
            Trace.WriteLine(file.Headers.ContentDisposition.FileName);
            Trace.WriteLine("Server file path: " + file.LocalFileName);
        }

        if (httpRequest.Files.Count > 0)
        {
            foreach (string file in httpRequest.Files)
            {

                var postedFile = httpRequest.Files[file];
                var filePath = HttpContext.Current.Server.MapPath("~/" + postedFile.FileName);
                postedFile.SaveAs(filePath);
                // NOTE: To store in memory use postedFile.InputStream
            }

            return Request.CreateResponse(HttpStatusCode.Created);
        }

        return Request.CreateResponse(HttpStatusCode.BadRequest);
    }

我已经坚持了 2 天,这让我发疯。我已经多次切碎并更改了我的代码,但每次我都有不同的问题。除了在服务器上正确读取 headers 之外,这是我最接近使我的代码正常工作的一次。

我会永远感激那个帮助我的人。

您的客户端很可能是 Android 应用程序。您在那里使用 Java.Lang.String.Format,并且 java 格式字符串的语法与 .NET 格式字符串不同,因此您的 {0} {1} 等占位符不会扩展。要修复,只需使用常规 .NET String.Format.