Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
538 views
in Technique[技术] by (71.8m points)

c# - Since WebClient's uploadData doesn't encode data, then what will be the effect of adding a "Content-Type", "multipart/form-data" header to it

C#'s uploadData method doesn't encode the data that is being sent. So, if I send a file over (after converting it into bytes) using this method, and the receiving side is looking for a multiform/form-data post, then it will obviously not work. Will adding a header like :

WebClient c = new WebClient();
c.Headers.Add("Content-Type", "multipart/form-data");

make it send the data encrypted as multiform, or will the data be still not encrypted (and hence unparseable by servers expecting multiform data) ?

Note that I can't use WebClient's uploadFile, as I don't have permission to get the file path location on the client side (I just have a stream, that I can convert to bytes)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Why don't you use UploadFile of WebClient over https if you want it to be secure? and that will automatically take care of adding multipart/form-data.

Example using UploadFile

http://msdn.microsoft.com/en-us/library/36s52zhs.aspx

And one more thing, encoding and encrypting are 2 different things.

Edit:

You should probably tag your question as Silverlight if you you are using WebClient in your WebClient project. Anyways, WebClient class in SL doesn't have any UploadData method. See this for more info:

http://msdn.microsoft.com/en-us/library/system.net.webclient%28v=vs.95%29.aspx

Anyways, here is the working solution to your problem:

In your button click, have this code:

OpenFileDialog dialog = new OpenFileDialog();
            bool? retVal = dialog.ShowDialog();
            if (retVal.HasValue && retVal == true)
            {
                using (Stream stream = dialog.File.OpenRead())
                {
                    MemoryStream memoryStream = new MemoryStream();
                    stream.CopyTo(memoryStream);
                    WebClient webClient = new WebClient();
                    webClient.Headers["Content-type"] = "multipart/form-data; boundary=---------------------------" + _boundaryNo;
                    webClient.OpenWriteAsync(new Uri("http://localhost:1463/Home/File", UriKind.Absolute), "POST", new { Stream = memoryStream, FileName = dialog.File.Name });
                    webClient.OpenWriteCompleted += new OpenWriteCompletedEventHandler(webClient_OpenWriteCompleted);
                }
            } 

and the event itself:

void webClient_OpenWriteCompleted(object sender, OpenWriteCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                Stream responseStream = e.Result as Stream;                
                dynamic obj = e.UserState;
                MemoryStream memoryStream = obj.Stream as MemoryStream;
                string fileName = obj.FileName;
                if (responseStream != null && memoryStream != null)
                {
                    string headerTemplate = string.Format("-----------------------------{0}
", _boundaryNo);

                    memoryStream.Position = 0;
                    byte[] byteArr = memoryStream.ToArray();
                    string data = headerTemplate + string.Format("Content-Disposition: form-data; name="pic"; filename="{0}"
Content-Type: application/octet-stream

", fileName);
                    byte[] header = Encoding.UTF8.GetBytes(data);
                    responseStream.Write(header, 0, header.Length);

                    responseStream.Write(byteArr, 0, byteArr.Length);
                    header = Encoding.UTF8.GetBytes("
");
                    responseStream.Write(byteArr, 0, byteArr.Length);

                    byte[] trailer = System.Text.Encoding.UTF8.GetBytes(string.Format("-----------------------------{0}--
", _boundaryNo));
                    responseStream.Write(trailer, 0, trailer.Length);                    
                }
                memoryStream.Close();
                responseStream.Close();
            }
        }

where _boundaryNo is private string _boundaryNo = DateTime.Now.Ticks.ToString("x");

I had it working with Asp.Net MVC 4 and Silverlight 5.

Good luck :)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...