C#アナログ提出添付ファイル(input type=file)付きフォーム

17372 ワード

今日あるAPIを呼び出す时、ドキュメントの中の伝入パラメータに対して:File[]のタイプ、感じはとても熟知していないで、手がつけられません!通常の方法でjsonパラメータにfileのバイナリデータを加えてコミットし、ずっとエラー(パラメータエラー)を報告します!その後いろいろな相談を経て,一つの種類を変えなければならない.
フォームの送信方法、すなわち、添付ファイル付きフォームの送信をシミュレートします.添付ファイル付きフォームを提出するためのクラスがネット上に盗まれました!使用方法は次のとおりです.
 
使用  参照コード(ツールクラスコードは次のとおりです):
                //    

                FormUpload.FileParameter file = new FormUpload.FileParameter(File.ReadAllBytes("D://TestAdvertiserFile.jpg"), "TestAdvertiserFile.jpg");



                //    

                Dictionary<string, object> postParams = new Dictionary<string, object>();

                postParams.Add("demoId", 3);

                postParams.Add("token", "TnQqQSDFSDI#2121231");

                postParams.Add("advertiserId", input.SinaInput.Id);

                postParams.Add("name", input.SinaInput.Name);

                postParams.Add("industry",input.SinaInput.Industry);



                //        ,       ,        

                postParams.Add("qualificationFiles", file);



                //

                var httpWebResp = FormUpload.MultipartFormDataPost("http://amp.ad.sina.com.cn/sax/interface/advertiser/upload.action", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.3 Safari/535.19", postParams);



                Stream instream = httpWebResp.GetResponseStream();

                StreamReader sr = new StreamReader(instream,Encoding.UTF8);

                //      (html)  

                string response = sr.ReadToEnd();

                sr.Close();

 
 
 
ツールクラスは次のとおりです.
    // Implements multipart/form-data POST in C# http://www.ietf.org/rfc/rfc2388.txt

    // http://www.briangrinstead.com/blog/multipart-form-post-in-c

    public static class FormUpload

    {

        private static readonly Encoding encoding = Encoding.UTF8;



        public static HttpWebResponse MultipartFormDataPost(string postUrl, string userAgent, Dictionary<string, object> postParameters)

        {

            string formDataBoundary = String.Format("----------{0:N}", Guid.NewGuid());

            string contentType = "multipart/form-data; boundary=" + formDataBoundary;



            byte[] formData = GetMultipartFormData(postParameters, formDataBoundary);



            return PostForm(postUrl, userAgent, contentType, formData);

        }



        private static HttpWebResponse PostForm(string postUrl, string userAgent, string contentType, byte[] formData)

        {

            HttpWebRequest request = WebRequest.Create(postUrl) as HttpWebRequest;



            if (request == null)

            {

                throw new NullReferenceException("request is not a http request");

            }



            // Set up the request properties.

            request.Method = "POST";

            request.ContentType = contentType;

            request.UserAgent = userAgent;

            request.CookieContainer = new CookieContainer();

            request.ContentLength = formData.Length;



            // You could add authentication here as well if needed:

            // request.PreAuthenticate = true;

            // request.AuthenticationLevel = System.Net.Security.AuthenticationLevel.MutualAuthRequested;

            // request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(System.Text.Encoding.Default.GetBytes("username" + ":" + "password")));



            // Send the form data to the request.

            using (Stream requestStream = request.GetRequestStream())

            {

                requestStream.Write(formData, 0, formData.Length);

                requestStream.Close();

            }



            return request.GetResponse() as HttpWebResponse;

        }



        private static byte[] GetMultipartFormData(Dictionary<string, object> postParameters, string boundary)

        {

            Stream formDataStream = new System.IO.MemoryStream();

            bool needsCLRF = false;



            foreach (var param in postParameters)

            {

                // Thanks to feedback from commenters, add a CRLF to allow multiple parameters to be added.

                // Skip it on the first parameter, add it to subsequent parameters.

                if (needsCLRF)

                    formDataStream.Write(encoding.GetBytes("\r
"), 0, encoding.GetByteCount("\r
")); needsCLRF = true; if (param.Value is FileParameter) { FileParameter fileToUpload = (FileParameter)param.Value; // Add just the first part of this param, since we will write the file data directly to the Stream string header = string.Format("--{0}\r
Content-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r
Content-Type: {3}\r
\r
", boundary, param.Key, fileToUpload.FileName ?? param.Key, fileToUpload.ContentType ?? "application/octet-stream"); formDataStream.Write(encoding.GetBytes(header), 0, encoding.GetByteCount(header)); // Write the file data directly to the Stream, rather than serializing it to a string. formDataStream.Write(fileToUpload.File, 0, fileToUpload.File.Length); } else { string postData = string.Format("--{0}\r
Content-Disposition: form-data; name=\"{1}\"\r
\r
{2}
", boundary, param.Key, param.Value); formDataStream.Write(encoding.GetBytes(postData), 0, encoding.GetByteCount(postData)); } } // Add the end of the request. Start with a newline string footer = "\r
--
" + boundary + "--\r
"; formDataStream.Write(encoding.GetBytes(footer), 0, encoding.GetByteCount(footer)); // Dump the Stream into a byte[] formDataStream.Position = 0; byte[] formData = new byte[formDataStream.Length]; formDataStream.Read(formData, 0, formData.Length); formDataStream.Close(); return formData; } public class FileParameter { public byte[] File { get; set; } public string FileName { get; set; } public string ContentType { get; set; } public FileParameter(byte[] file) : this(file, null) { } public FileParameter(byte[] file, string filename) : this(file, filename, null) { } public FileParameter(byte[] file, string filename, string contenttype) { File = file; FileName = filename; ContentType = contenttype; } } }