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

时间:2016-05-29 20:05:42

标签: c# asp.net-web-api httpwebrequest multipartform-data

我无法读取文件名以及来自客户端的其他值。我使用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;
        }
    }

在服务器端没有检索到客户端写入的内容处理值。在服务器端,文件名读作" {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天了,这让我发疯了。我已经多次切碎并更改了我的代码,但每次都有不同的问题。这是我最接近使我的代码工作,除了在服务器上正确读取标题。

我将永远感谢能帮助我的人。

1 个答案:

答案 0 :(得分:1)

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