iT邦幫忙

0

【求救】【已解決!】該網頁內容如何用C#達成?

<body MS_POSITIONING="GridLayout">
 <table border=1>
	<td valign=top>
<--<form name="PostForm1" method="post" action="http://localhost/NTS/Receive/NtsCollect.aspx" id="PostForm1" enctype="multipart/form-data">-->
				
<form name="PostForm1" method="post" 					
 <table>
  <tr>
		集信データ送信テスト
	</tr>
	<tr>
	<td>ID:</td>
 <td><INPUT type="text" name="ID"    value="000000000000000000000000000000000000"></td>
						</tr>
						<tr>
	<td>企業コード:</td>
								<td><INPUT type="text" name="USER" value="000000000117"></td>
						</tr>
						<tr>
							<td>店舗コード:</td>
							<td><INPUT type="text" name="SHOP" value="0000000000001"></td>
						</tr>
						<tr>
							<td>POSNo.(端末コード):</td>
							<td><INPUT type="text" name="TERM" value="01"></td>
						</tr>
						<tr>
							<td>ファイル種別:</td>
							<td><INPUT type="text" name="FILETYPE" value="SMRY001"></td>
						</tr>
						<tr>
							<td>営業日(yyyymmdd):</td>
							<td><INPUT type="text" name="SALES_DATE" value="20080512"></td>
						</tr>
						<tr>
							<td>同日精算回数:</td>
							<td><INPUT type="text" name="CLOSE_COUNTER" value="01"></td>
						</tr>
						<tr>
							<td>データNo.:</td>
							<td><INPUT type="text" name="BATCHID" value="00001"></td>
						</tr>

<!--
-->
						<tr>
							<td>ファイル:</td>
							<td><input name="FILENAME" id="FILENAME" type="file" /></td>
						</tr>

						<tr>
							<td>
								<input type="submit" name="Button1" value="送信" id="Button1" />
								<input type="reset" name="Button2" value="クリア" id="Button2" />
							</td>
						</tr>
					</table>
				</form>
			</td>
            
   
   
 

 問了GOOGLE老師寫出來的東西,但總覺得方向一直是錯的!!

 private void submit_Click_1(object sender, EventArgs e)
        {
            
            //string ID = textBox1.Text;
            /*string USER = textBox2.Text;
            string SHOP = textBox3.Text;
            string TERM = textBox4.Text;
            string FILETYPE = textBox5.Text;
            string SALES_DATE = textBox6.Text;
            string CLOSE_COUNTER = textBox7.Text;
            string BATCHID = textBox8.Text;
            //string USER = textBox2.Text;*/

            ASCIIEncoding encoding = new ASCIIEncoding();
            string ID = "000000000000000000000000000000000000";
            byte[] data1 = Encoding.UTF8.GetBytes(ID);

            string USER = "000000000117";
            byte[] data2 = Encoding.UTF8.GetBytes(USER);

            string SHOP = "0000000000001";
            byte[] data3 = Encoding.UTF8.GetBytes(SHOP);

            string TERM = "01";
            byte[] data4 = Encoding.UTF8.GetBytes(TERM);

            string FILETYPE = "SMRY001";
            byte[] data5 = Encoding.UTF8.GetBytes(FILETYPE);

            string SALES_DATE = "20080512";
            byte[] data6 = Encoding.UTF8.GetBytes(SALES_DATE);

            string CLOSE_COUNTER = "01";
            byte[] data7 = Encoding.UTF8.GetBytes(CLOSE_COUNTER);

            string BATCHID = "00001";
            byte[] data8 = Encoding.UTF8.GetBytes(BATCHID);

            //string ID = "SMRY001";
            //byte[] data = Encoding.UTF8.GetBytes(FILETYPE);

            

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://fortune04/NTS/Receive/NtsCollect.aspx");
            request.Method = "POST";
            //request.ContentType = "application/x-www-form-urlencoded";
            /*request.ContentLength = data1.LongLength;
            request.ContentLength = data2.LongLength;
            request.ContentLength = data3.Length;
            request.ContentLength = data4.Length;
            request.ContentLength = data5.Length;
            request.ContentLength = data6.Length;
            request.ContentLength = data7.Length;
            request.ContentLength = data8.Length;*/

            request.ContentType = "multipart/form-data";

            Stream stream = request.GetRequestStream();
            //stream.Write(data1, 0, data1.Length);
            //stream.Write(data2, 0, data2.Length);
            //stream.Write(data3, 0, data3.Length);
            //stream.Write(data4, 0, data4.Length);
            //stream.Write(data5, 0, data5.Length);
            //stream.Write(data6, 0, data6.Length);
            //stream.Write(data7, 0, data7.Length);
            //stream.Write(data8, 0, data8.Length);
            //stream.Write(data, 0, data.Length);
            //stream.Close();
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
           
            stream = response.GetResponseStream();

            StreamReader sr = new StreamReader(stream);
            MessageBox.Show(sr.ReadToEnd());
            sr.Close();
            stream.Close();



           


        }

sakashi大大熱心教學後變成以下結果,看起來是有跟伺服器有建立溝通了。

現在的問題是該如何上傳XML檔案,並讓結果與網頁相同。。。

enctype="multipart/form-data" <--這個怎麼實現啊TAT

string poststring ="ID=000000000000000000000000000000000000&USER=000000000117&SHOP=0000000000001&TERM=01&FILETYPE=SMRY001&SALES_DATE=20080513&CLOSE_COUNTER=01&CLOSE_COUNTER=01&BATCHID=00001";

  byte[]data = Encoding.ASCII.GetBytes(poststring);
  string url = "http://fortune04/NTS/Receive/NtsCollect.aspx";
  HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
  request.Method = "POST";
  request.ContentType = "application/x-www-form-urlencoded";
  request.ContentLength = data.LongLength;
  Stream stream = request.GetRequestStream();
  stream.Write(data, 0, data.Length);
  
  HttpWebResponse response = (HttpWebResponse)request.GetResponse();
  stream = response.GetResponseStream();
  StreamReader sr = new StreamReader(stream);
  MessageBox.Show(sr.ReadToEnd());
  sr.Close();
  stream.Close();

圖片:
https://ithelp.ithome.com.tw/upload/images/20181217/201140429xTfevEiqL.png
https://ithelp.ithome.com.tw/upload/images/20181217/201140426dzaognV5x.png

目標:
 1.用C#達成跟上述程式一樣的結果。
 2.目前得知他是用HTTP PORT 方式將表單及檔案丟回至SERVER。
 3.沒看到有連資料庫相關程式碼。(奇怪?)
 4.求各路高手幫幫在東京求生的網路工程師TAT(啊靠,明明就不是我專門硬丟給我!)
 5.日文鍵盤很難打!!!
*不好意思,排版有點亂。。。

看更多先前的討論...收起先前的討論...
lard0921 iT邦新手 4 級 ‧ 2018-12-17 10:18:53 檢舉
おつからさま.....學習日語中 路過  
Homura iT邦高手 1 級 ‧ 2018-12-17 10:25:40 檢舉
@lard0921
日文的辛苦是おつかれさま....
narumi iT邦新手 5 級 ‧ 2018-12-17 10:40:54 檢舉
哦,這新手任務也超難 一一
@lard0921 是 お疲れ様。
有日文問題可以一起提出討論啊,能幫上您的話。
lard0921 iT邦新手 4 級 ‧ 2018-12-17 11:39:11 檢舉
哈 打錯啦 謝謝糾正 3Q
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
1
小碼農米爾
iT邦高手 1 級 ‧ 2018-12-17 20:31:59
最佳解答

初版先給大大參考,目前用 MemoryStream 所以不能上傳太大的檔案。
/images/emoticon/emoticon16.gif

WPF 程式:

private void Submit_Click(object sender, RoutedEventArgs e)
{
    //邊界
    var boundary = "-----" + DateTime.Now.Ticks.ToString("x");
    
    //Fiddler 不能攔截 127.0.0.1 的網址,需要用電腦名稱代替
    var request = (HttpWebRequest)HttpWebRequest.Create("http://電腦名稱/WebformPostTest_Web/Test.aspx");
    request.Method = "POST";
    request.ContentType = "multipart/form-data; boundary=" + boundary;

    //測試時設定 Proxy 到 Fiddler 上
    //request.Proxy = new WebProxy("127.0.0.1", 8888);

    var fieldTemplate = "";
    fieldTemplate += "--"+ boundary + "\r\n";
    fieldTemplate += "Content-Disposition: form-data; name=\"{0}\"\r\n";
    fieldTemplate += "\r\n";
    fieldTemplate += "{1}\r\n";

    var fileTemplate = "";
    fileTemplate += "--" + boundary + "\r\n";
    fileTemplate += "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n";
    fileTemplate += "Content-Type: application/octet-stream\r\n\r\n";

    var bytes = null as byte[];
    //檔案太大的話需要換寫法,不能用 MemoryStream
    using (var ms = new MemoryStream())
    {
        bytes = Encoding.UTF8.GetBytes(string.Format(fieldTemplate, "USER", USER.Text));
        ms.Write(bytes, 0, bytes.Length);
        bytes = Encoding.UTF8.GetBytes(string.Format(fieldTemplate, "SHOP", SHOP.Text));
        ms.Write(bytes, 0, bytes.Length);
        bytes = Encoding.UTF8.GetBytes(string.Format(fieldTemplate, "TERM", TERM.Text));
        ms.Write(bytes, 0, bytes.Length);
        bytes = Encoding.UTF8.GetBytes(string.Format(fieldTemplate, "FILETYPE", FILETYPE.Text));
        ms.Write(bytes, 0, bytes.Length);
        bytes = Encoding.UTF8.GetBytes(string.Format(fieldTemplate, "SALES_DATE", SALES_DATE.Text));
        ms.Write(bytes, 0, bytes.Length);
        bytes = Encoding.UTF8.GetBytes(string.Format(fieldTemplate, "CLOSE_COUNTER", CLOSE_COUNTER.Text));
        ms.Write(bytes, 0, bytes.Length);
        bytes = Encoding.UTF8.GetBytes(string.Format(fieldTemplate, "BATCHID", USER.Text));
        ms.Write(bytes, 0, bytes.Length);

        //檔案
        var filePath = FILENAME.Content.ToString();
        bytes = Encoding.UTF8.GetBytes(string.Format(fileTemplate, "FILENAME", System.IO.Path.GetFileName(filePath)));
        ms.Write(bytes, 0, bytes.Length);

        using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
        {
            fs.Seek(0, SeekOrigin.Begin);
            fs.CopyTo(ms);
        }
        
        //結尾
        bytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
        ms.Write(bytes, 0, bytes.Length);

        //Post
        bytes = ms.ToArray();
    }

    request.ContentLength = bytes.Length;
    var requestStream = request.GetRequestStream();
    requestStream.Write(bytes, 0, bytes.Length);
    requestStream.Close();

    var response = (HttpWebResponse)request.GetResponse();
}

我好像沒加到 ID 欄位。
/images/emoticon/emoticon25.gif


更新:
包裝成 Class,並改寫 Stream 可以上傳大檔案。

Main

private void Submit_Click(object sender, RoutedEventArgs e)
{
    //邊界
    var boundary = "-----" + DateTime.Now.Ticks.ToString("x");
    
    //Fiddler 不能攔截 127.0.0.1 的網址,需要用電腦名稱代替
    var request = (HttpWebRequest)HttpWebRequest.Create(
        "http://電腦名稱/WebformPostTest_Web/Test.aspx");
    request.Method = "POST";
    request.ContentType = "multipart/form-data; boundary=" + boundary;

    //測試時設定 Proxy 到 Fiddler 上
    //request.Proxy = new WebProxy("127.0.0.1", 8888);

    var formData = new FormData(boundary, Encoding.UTF8);
    formData.Append(new FieldItem("USER", USER.Text));
    formData.Append(new FieldItem("SHOP", SHOP.Text));
    formData.Append(new FieldItem("TERM", TERM.Text));
    formData.Append(new FieldItem("FILETYPE", FILETYPE.Text));
    formData.Append(new FieldItem("SALES_DATE", SALES_DATE.Text));
    formData.Append(new FieldItem("CLOSE_COUNTER", CLOSE_COUNTER.Text));
    formData.Append(new FieldItem("BATCHID", BATCHID.Text));
    formData.Append(new FileItem("FILENAME",
        System.IO.Path.GetFileName(FILENAME.Content.ToString()), 
        FILENAME.Content.ToString()));
    formData.Append(new FileItem("FILENAME",
        System.IO.Path.GetFileName(FILENAME2.Content.ToString()), 
        FILENAME2.Content.ToString()));

    request.ContentLength = formData.GetLength();

    var requestStream = request.GetRequestStream();
    formData.Write(requestStream);
    requestStream.Close();

    var response = (HttpWebResponse)request.GetResponse();
}

Multipart.cs

namespace Multipart
{
    /// <summary>
    /// 表單
    /// </summary>
    public class FormData
    {
        /// <summary>
        /// 邊界
        /// </summary>
        public string Boundary { get; set; }

        /// <summary>
        /// 表單編碼
        /// </summary>
        public Encoding Encoding { get; set; }

        public FormData(string boundary, Encoding encoding)
        {
            Boundary = boundary;
            Encoding = encoding;
        }

        /// <summary>
        /// 緩衝區大小,預設100KB
        /// </summary>
        public int BufferSize { get; set; } = 102400;

        /// <summary>
        /// 所有表單項目
        /// </summary>
        private List<FormDataItem> itemList { get; set; } = new List<FormDataItem>();

        /// <summary>
        /// 將項目加入表單
        /// </summary>
        /// <param name="item"></param>
        public void Append(FormDataItem item)
        {
            itemList.Add(item);
        }

        /// <summary>
        /// 取得表單長度
        /// </summary>
        /// <returns></returns>
        public long GetLength()
        {
            var length = (long)0;
            foreach (var item in itemList)
            {
                length += item.GetLength(Boundary, Encoding);
            }
            //結尾
            length += Encoding.UTF8.GetBytes("--" + Boundary + "--\r\n").Length;
            return length;
        }

        /// <summary>
        /// 將表單寫入串流
        /// </summary>
        /// <param name="stream"></param>
        public void Write(Stream stream)
        {
            foreach (var item in itemList)
            {
                item.Write(stream, Boundary, Encoding, BufferSize);
            }
            //結尾
            var bytes = Encoding.UTF8.GetBytes("--" + Boundary + "--\r\n");
            stream.Write(bytes, 0, bytes.Length);
        }
    }

    /// <summary>
    /// 表單項目
    /// </summary>
    public abstract class FormDataItem
    {
        /// <summary>
        /// 取得項目位元組長度
        /// </summary>
        /// <param name="boundary"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        internal abstract long GetLength(string boundary, Encoding encoding);

        /// <summary>
        /// 將項目寫入串流
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="boundary"></param>
        /// <param name="encoding"></param>
        /// <param name="bufferSize"></param>
        internal abstract void Write(Stream stream, string boundary, Encoding encoding, int bufferSize);
    }

    /// <summary>
    /// 一般欄位
    /// </summary>
    public class FieldItem : FormDataItem
    {
        /// <summary>
        /// 樣板
        /// </summary>
        private static readonly string template;

        static FieldItem()
        {
            var temp = "";
            temp += "--{0}\r\n";
            temp += "Content-Disposition: form-data; name=\"{1}\"\r\n";
            temp += "\r\n";
            temp += "{2}\r\n";
            template = temp;
        }

        /// <summary>
        /// 表單的Key
        /// </summary>
        private string Key { get; set; }

        /// <summary>
        /// 欄位的值
        /// </summary>
        private string Value { get; set; }

        /// <summary>
        /// 一般欄位
        /// </summary>
        /// <param name="key">表單的Key</param>
        /// <param name="value">欄位的值</param>
        public FieldItem(string key, string value)
        {
            Key = key;
            Value = value;
        }

        /// <summary>
        /// Format 快取
        /// </summary>
        private byte[] cache = null;
        private byte[] Format(string boundary, Encoding encoding)
        {
            if (cache == null)
            {
                cache = encoding.GetBytes(string.Format(template, boundary, Key, Value));
            }
            return cache;
        }

        internal override long GetLength(string boundary, Encoding encoding)
        {
            return this.Format(boundary, encoding).Length;
        }

        internal override void Write(Stream stream, string boundary, Encoding encoding, int bufferSize)
        {
            //寫入 template
            var bytes = this.Format(boundary, encoding);
            stream.Write(bytes, 0, bytes.Length);
        }
    }

    /// <summary>
    /// 檔案
    /// </summary>
    public class FileItem : FormDataItem
    {
        /// <summary>
        /// 樣板
        /// </summary>
        private static readonly string template;

        static FileItem()
        {
            var temp = "";
            temp += "--{0}\r\n";
            temp += "Content-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\n";
            temp += "Content-Type: application/octet-stream\r\n\r\n";
            template = temp;
        }

        /// <summary>
        /// 表單的Key
        /// </summary>
        private string Key { get; set; }

        /// <summary>
        /// 檔案名稱
        /// </summary>
        private string FileName { get; set; }

        /// <summary>
        /// 檔案路徑
        /// </summary>
        private string FilePath { get; set; }

        /// <summary>
        /// 檔案
        /// </summary>
        /// <param name="key">表單的Key</param>
        /// <param name="fileName">檔案名稱</param>
        /// <param name="filePath">檔案路徑</param>
        public FileItem(string key, string fileName, string filePath)
        {
            Key = key;
            FileName = fileName;
            FilePath = filePath;
        }

        /// <summary>
        /// Format 快取
        /// </summary>
        private byte[] cache = null;
        private byte[] Format(string boundary, Encoding encoding)
        {
            if (cache == null)
            {
                cache = encoding.GetBytes(string.Format(template, boundary, Key, FileName, FilePath));
            }
            return cache;
        }

        internal override long GetLength(string boundary, Encoding encoding)
        {
            return this.Format(boundary, encoding).Length +
                new FileInfo(FilePath).Length + encoding.GetBytes("\r\n").Length;
        }

        internal override void Write(Stream stream, string boundary, Encoding encoding, int bufferSize)
        {
            //寫入 template
            var bytes = this.Format(boundary, encoding);
            stream.Write(bytes, 0, bytes.Length);

            //寫入檔案
            var buffer = new byte[bufferSize];
            using (var fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read))
            {
                fs.Seek(0, SeekOrigin.Begin);

                var readCount = 0;
                while (true)
                {
                    readCount = fs.Read(buffer, 0, bufferSize);
                    if (readCount == 0)
                        break;
                    stream.Write(buffer, 0, readCount);
                }
            }

            //寫入最後的換行符號
            bytes = encoding.GetBytes("\r\n");
            stream.Write(bytes, 0, bytes.Length);
        }
    }
}

POST 出去的內容大概長這樣:

-------8d66477628c4ae8
Content-Disposition: form-data; name="USER"

000000000117
-------8d66477628c4ae8
Content-Disposition: form-data; name="SHOP"

0000000000001
-------8d66477628c4ae8
Content-Disposition: form-data; name="TERM"

01
-------8d66477628c4ae8
Content-Disposition: form-data; name="FILETYPE"

SMRY001
-------8d66477628c4ae8
Content-Disposition: form-data; name="SALES_DATE"

20080512
-------8d66477628c4ae8
Content-Disposition: form-data; name="CLOSE_COUNTER"

01
-------8d66477628c4ae8
Content-Disposition: form-data; name="BATCHID"

00001
-------8d66477628c4ae8
Content-Disposition: form-data; name="FILENAME"; filename="aaa.txt"
Content-Type: application/octet-stream

aaaaaa
bbbbbb
cccccc
-------8d66477628c4ae8--

https://ithelp.ithome.com.tw/upload/images/20181218/20106865fqM8LYUAo8.jpg

檔案選擇:

private void File_Click(object sender, RoutedEventArgs e)
{
    var openFileDialog = new Microsoft.Win32.OpenFileDialog();
    var result = openFileDialog.ShowDialog();
    if (result == true)
    {
        //將檔案路徑存入 Textbox 或 Label
        FILENAME.Content = openFileDialog.FileName;
    }
}

2019/01/10 更新程式
FormData 新增 ProgressChanged 事件,可以取得 百分比上傳位元數上傳項目數 等進度資訊。

用法:

try
{
    //邊界
    var boundary = "-----" + DateTime.Now.Ticks.ToString("x");

    var request = (HttpWebRequest)HttpWebRequest.Create("http://127.0.0.1/WebformPostTest_Web/Test.aspx");
    request.Method = "POST";
    request.ContentType = "multipart/form-data; boundary=" + boundary;

    //測試時設定 Proxy 到 Fiddler 上
    //request.Proxy = new WebProxy("127.0.0.1", 8888);

    var formData = new FormData(boundary, Encoding.UTF8);
    formData.Append(new FieldItem("USER", USER.Text));
    formData.Append(new FieldItem("SHOP", SHOP.Text));
    formData.Append(new FieldItem("TERM", TERM.Text));
    formData.Append(new FieldItem("FILETYPE", FILETYPE.Text));
    formData.Append(new FieldItem("SALES_DATE", SALES_DATE.Text));
    formData.Append(new FieldItem("CLOSE_COUNTER", CLOSE_COUNTER.Text));
    formData.Append(new FieldItem("BATCHID", BATCHID.Text));
    formData.Append(new FileItem("FILENAME",
        System.IO.Path.GetFileName(FILENAME.Content.ToString()),
        FILENAME.Content.ToString()));
    formData.Append(new FileItem("FILENAME",
        System.IO.Path.GetFileName(FILENAME2.Content.ToString()),
        FILENAME2.Content.ToString()));

    request.ContentLength = formData.GetLength();

    //開新執行緒上傳,才不會卡住UI
    await Task.Run(() =>
    {
        //進度處理
        formData.ProgressChanged += (s, ee) =>
        {
            //呼叫主執行緒更新UI
            this.Dispatcher.Invoke(() =>
            {
                //只想計算檔案的話,將 PostFiles 扣掉欄位數就等於檔案數
                var postFile = ee.PostItems - 7 > 0 ? ee.PostItems - 7 : 0;
                var totalFile = ee.TotalItems - 7 > 0 ? ee.TotalItems - 7 : 0;
                Process.Content =
                    $"百分比: {ee.Percentage},上傳位元數: {ee.PostBytes}/{ee.TotalBytes},上傳檔案數: {postFile}/{totalFile}";
            });
        };

        var requestStream = request.GetRequestStream();
        formData.Write(requestStream);
        requestStream.Close();

        var response = (HttpWebResponse)request.GetResponse();
    });
}
catch(Exception ex)
{
}

Multipart.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Multipart
{
    /// <summary>
    /// 表單
    /// </summary>
    public class FormData
    {
        /// <summary>
        /// 邊界
        /// </summary>
        public string Boundary { get; set; }

        /// <summary>
        /// 表單編碼
        /// </summary>
        public Encoding Encoding { get; set; }

        public FormData(string boundary, Encoding encoding)
        {
            Boundary = boundary;
            Encoding = encoding;
        }

        /// <summary>
        /// 緩衝區大小,預設100KB
        /// </summary>
        public int BufferSize { get; set; } = 102400;

        /// <summary>
        /// 所有表單項目
        /// </summary>
        private List<FormDataItem> itemList { get; set; } = new List<FormDataItem>();

        /// <summary>
        /// 將項目加入表單
        /// </summary>
        /// <param name="item"></param>
        public void Append(FormDataItem item)
        {
            itemList.Add(item);
        }

        /// <summary>
        /// 取得表單長度
        /// </summary>
        /// <returns></returns>
        public long GetLength()
        {
            var length = (long)0;
            foreach (var item in itemList)
            {
                length += item.GetLength(Boundary, Encoding);
            }
            //結尾
            length += Encoding.UTF8.GetBytes("--" + Boundary + "--\r\n").Length;
            return length;
        }

        /// <summary>
        /// 將表單寫入串流
        /// </summary>
        /// <param name="stream"></param>
        public void Write(Stream stream)
        {
            var postBytes = (long)0;
            var totalBytes = this.GetLength();
            var postItems = 0;
            var totalItems = itemList.Count;

            //觸發進度事件
            var progressFunc = (Action)(() =>
            {
                var process = (int)Math.Ceiling(((double)(postBytes)) / totalBytes * 100);

                OnProgress(postBytes, totalBytes, postItems, totalItems, process);
            });

            foreach (var item in itemList)
            {
                item.ProgressChanged += (s, e) =>
                {
                    postBytes += e.PostBytes;
                    progressFunc();
                };
                item.Write(stream, Boundary, Encoding, BufferSize);
                postItems++;
            }
            //結尾
            var bytes = Encoding.UTF8.GetBytes("--" + Boundary + "--\r\n");
            stream.Write(bytes, 0, bytes.Length);
            
            postBytes += bytes.Length;
            progressFunc();
        }

        /// <summary>
        /// 上傳進度事件
        /// </summary>
        public event FormDataProgressChangedEventHandler ProgressChanged;

        protected virtual void OnProgress(long postBytes, long totalBytes, int postItems, int totalItems, int percentage)
        {
            ProgressChanged?.Invoke(this, new FormDataProgressChangedEventArgs(postBytes, totalBytes, postItems, totalItems, percentage));
        }
    }

    /// <summary>
    /// 表單項目
    /// </summary>
    public abstract class FormDataItem
    {
        /// <summary>
        /// 取得項目位元組長度
        /// </summary>
        /// <param name="boundary"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        internal abstract long GetLength(string boundary, Encoding encoding);

        /// <summary>
        /// 將項目寫入串流
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="boundary"></param>
        /// <param name="encoding"></param>
        /// <param name="bufferSize"></param>
        internal abstract void Write(Stream stream, string boundary, Encoding encoding, int bufferSize);

        /// <summary>
        /// 上傳進度事件
        /// </summary>
        internal event FormDataItemProgressChangedEventHandler ProgressChanged;

        protected virtual void OnProgress(long postBytes)
        {
            ProgressChanged?.Invoke(this, new FormDataItemProgressChangedEventArgs(postBytes));
        }
    }

    /// <summary>
    /// 一般欄位
    /// </summary>
    public class FieldItem : FormDataItem
    {
        /// <summary>
        /// 樣板
        /// </summary>
        private static readonly string template;

        static FieldItem()
        {
            var temp = "";
            temp += "--{0}\r\n";
            temp += "Content-Disposition: form-data; name=\"{1}\"\r\n";
            temp += "\r\n";
            temp += "{2}\r\n";
            template = temp;
        }

        /// <summary>
        /// 表單的Key
        /// </summary>
        private string Key { get; set; }

        /// <summary>
        /// 欄位的值
        /// </summary>
        private string Value { get; set; }

        /// <summary>
        /// 一般欄位
        /// </summary>
        /// <param name="key">表單的Key</param>
        /// <param name="value">欄位的值</param>
        public FieldItem(string key, string value)
        {
            Key = key;
            Value = value;
        }

        /// <summary>
        /// Format 暫存
        /// </summary>
        private byte[] cache = null;
        private byte[] Format(string boundary, Encoding encoding)
        {
            if (cache == null)
            {
                cache = encoding.GetBytes(string.Format(template, boundary, Key, Value));
            }
            return cache;
        }

        internal override long GetLength(string boundary, Encoding encoding)
        {
            return this.Format(boundary, encoding).Length;
        }

        internal override void Write(Stream stream, string boundary, Encoding encoding, int bufferSize)
        {
            //寫入 template
            var bytes = this.Format(boundary, encoding);
            stream.Write(bytes, 0, bytes.Length);

            //觸發進度事件
            OnProgress(bytes.Length);
        }
    }

    /// <summary>
    /// 檔案
    /// </summary>
    public class FileItem : FormDataItem
    {
        /// <summary>
        /// 樣板
        /// </summary>
        private static readonly string template;

        static FileItem()
        {
            var temp = "";
            temp += "--{0}\r\n";
            temp += "Content-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\n";
            temp += "Content-Type: application/octet-stream\r\n\r\n";
            template = temp;
        }

        /// <summary>
        /// 表單的Key
        /// </summary>
        private string Key { get; set; }

        /// <summary>
        /// 檔案名稱
        /// </summary>
        private string FileName { get; set; }

        /// <summary>
        /// 檔案路徑
        /// </summary>
        private string FilePath { get; set; }

        /// <summary>
        /// 檔案
        /// </summary>
        /// <param name="key">表單的Key</param>
        /// <param name="fileName">檔案名稱</param>
        /// <param name="filePath">檔案路徑</param>
        public FileItem(string key, string fileName, string filePath)
        {
            Key = key;
            FileName = fileName;
            FilePath = filePath;
        }

        /// <summary>
        /// Format 暫存
        /// </summary>
        private byte[] cache = null;
        private byte[] Format(string boundary, Encoding encoding)
        {
            if (cache == null)
            {
                cache = encoding.GetBytes(string.Format(template, boundary, Key, FileName, FilePath));
            }
            return cache;
        }

        internal override long GetLength(string boundary, Encoding encoding)
        {
            return this.Format(boundary, encoding).Length +
                new FileInfo(FilePath).Length + encoding.GetBytes("\r\n").Length;
        }

        internal override void Write(Stream stream, string boundary, Encoding encoding, int bufferSize)
        {
            //寫入 template
            var bytes = this.Format(boundary, encoding);
            stream.Write(bytes, 0, bytes.Length);

            //觸發進度事件
            OnProgress(bytes.Length);

            //寫入檔案
            var buffer = new byte[bufferSize];
            using (var fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read))
            {
                fs.Seek(0, SeekOrigin.Begin);

                var readCount = 0;
                while (true)
                {
                    readCount = fs.Read(buffer, 0, bufferSize);
                    if (readCount == 0)
                        break;
                    stream.Write(buffer, 0, readCount);

                    //觸發進度事件
                    OnProgress(readCount);
                }
            }

            //寫入最後的換行符號
            bytes = encoding.GetBytes("\r\n");
            stream.Write(bytes, 0, bytes.Length);

            //觸發進度事件
            OnProgress(bytes.Length);
        }
    }

    /// <summary>
    /// 處理 FormData ProgressChanged 事件的方法
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    public delegate void FormDataProgressChangedEventHandler(object sender, FormDataProgressChangedEventArgs e);

    /// <summary>
    /// FormData ProgressChanged 事件的資料
    /// </summary>
    public class FormDataProgressChangedEventArgs : EventArgs
    {
        public FormDataProgressChangedEventArgs(long postBytes, long totalBytes, int postItems, int totalItems, int percentage)
        {
            PostBytes = postBytes;
            TotalBytes = totalBytes;
            PostItems = postItems;
            TotalItems = totalItems;
            Percentage = percentage;
        }

        /// <summary>
        /// 已上傳位元數量
        /// </summary>
        public long PostBytes { get; }

        /// <summary>
        /// 全部位元數量
        /// </summary>
        public long TotalBytes { get; }

        /// <summary>
        /// 已上傳項目數量
        /// </summary>
        public int PostItems { get; set; }

        /// <summary>
        /// 全部項目數量
        /// </summary>
        public int TotalItems { get; set; }

        /// <summary>
        /// 整體百分比
        /// </summary>
        public int Percentage { get; }
    }

    /// <summary>
    /// 處理 FormDataItem ProgressChanged 事件的方法
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    internal delegate void FormDataItemProgressChangedEventHandler(object sender, FormDataItemProgressChangedEventArgs e);

    /// <summary>
    /// FormDataItem ProgressChanged 事件的資料
    /// </summary>
    internal class FormDataItemProgressChangedEventArgs : EventArgs
    {
        public FormDataItemProgressChangedEventArgs(long postBytes)
        {
            PostBytes = postBytes;
        }

        /// <summary>
        /// 送出的位元數量
        /// </summary>
        public long PostBytes { get; }
    }
}
2
海綿寶寶
iT邦大神 1 級 ‧ 2018-12-17 10:21:02

參考看看

其中
fileKeyName, filePath 用來說明上傳的檔案
stringDict 用來傳前面那些欄位(USER, SHOP, TERM...)

narumi iT邦新手 5 級 ‧ 2018-12-17 10:42:09 檢舉

這網頁我也有查到,但老實說我對他的內容不是很了解...(程式苦手)
是否大神您可以給小弟一個範例參考?

1
sakashi
iT邦新手 5 級 ‧ 2018-12-17 10:21:44

建議先找出NtsCollect.aspx在哪邊,在他的.cs檔案裡面應該就會有存取資料庫的部分的資訊
資料庫連結的路徑應該在web.config裡面的connectString裡面

看更多先前的回應...收起先前的回應...
narumi iT邦新手 5 級 ‧ 2018-12-17 10:39:44 檢舉

剛去看了一下,對方只丟了NtsCollect_TEST.html<--這網頁給我。。。
WEB.config沒有。

sakashi iT邦新手 5 級 ‧ 2018-12-17 11:00:18 檢舉

好吧~那用另一個方式來看好了
假設他是要你實做這個功能(資料庫也是新的)
步驟大概就是 :
1.建資料庫,然後自己連資料庫完成這個項目,資料表schema可以參考他上面提供給你的項目進行設計
2.設計新頁面/API去接你填寫資料後的資料Post過去的位置,如果要用它範例程式碼裡面的.aspx的話,在.cs裡面可以用Request.From(XXXXX)的方式取得。
3.再承接資料的地方實做連接資料庫的功能

大概是這樣的感覺吧 ?

narumi iT邦新手 5 級 ‧ 2018-12-17 11:41:56 檢舉

目前他是有一台server在接收這些資料,所以應該不用自己寫。
只是我實在搞不懂為啥他網頁寫的傳的到伺服器,但用C#卻實作不出來。
我卡在這裡。/images/emoticon/emoticon02.gif

sakashi iT邦新手 5 級 ‧ 2018-12-17 11:48:16 檢舉

我不大懂的地方是...你說用c#實作不出來的點在哪邊...?
你是要在.cs去做Post的行為而非在.aspx進行嗎?

如果是這樣的話就.aspx上面丟個button實作click事件,在click事件裡面用HttpWebRequest去實作就可以囉?

narumi iT邦新手 5 級 ‧ 2018-12-17 11:56:17 檢舉

對對對,差不多就這意思。
應該說,他網頁是用PORT方式在丟資料。
若用WINFROM做出一個一模一樣的東西要怎麼做呢?

網頁頁面
https://ithelp.ithome.com.tw/upload/images/20181217/20114042VBIaedATRd.png

WINFROM

https://ithelp.ithome.com.tw/upload/images/20181217/201140420jAZsy2nrv.png

sakashi iT邦新手 5 級 ‧ 2018-12-17 11:57:59 檢舉

一樣啊,你WinForm上面不是有個Submit按鈕,對那個按鈕實作Click事件,使用HttpRequest實作Post呼叫就可以囉

narumi iT邦新手 5 級 ‧ 2018-12-17 12:01:09 檢舉

HttpRequest<-我試過但做不出來,就不知道哪裡有問題.是我程式碼哪兒有少嗎?
還是我上面打的方向跟本錯誤啊TAT

narumi iT邦新手 5 級 ‧ 2018-12-17 12:49:58 檢舉

剛查了一下,若不用HttpRequest,改用WebClient的話也能達成同樣的結果嗎?

sakashi iT邦新手 5 級 ‧ 2018-12-17 13:40:08 檢舉

可以唷~

1
Luke
iT邦研究生 5 級 ‧ 2018-12-17 11:06:16

目前得知他是用HTTP PORT 方式將表單及檔案丟回至SERVER。

他會在WEB上,先『劉覽』,選出客戶端(Client) 檔案
去找他是否有用javascript 、 jquery、EasyUI ...等,AJAX方式送出
/images/emoticon/emoticon06.gif

沒看到有連資料庫相關程式碼。(奇怪?)
會不會要您自己去寫出來...

narumi iT邦新手 5 級 ‧ 2018-12-17 11:16:08 檢舉

目前他是有一台server在接收這些資料,所以應該不用自己寫。
只是我實在搞不懂為啥他網頁寫的傳的到伺服器,但用C#卻實作不出來。
我卡在這裡。

Luke iT邦研究生 5 級 ‧ 2018-12-17 13:23:24 檢舉

對 您說的『他是有一台server在接收這些資料』<==資料庫嗎?
所以您要找出,他怎樣去將資料,傳給這一台server

要嗎他跟您說,怎要寫用javascript 、 jquery、EasyUI ...等等方式,
要嗎他要您自己寫DAO、JDBC ...等connection 方式

/images/emoticon/emoticon10.gif

1
小魚
iT邦大師 1 級 ‧ 2018-12-17 14:56:06

這問題有點大,
所以原本的網頁是可以正常運作的嗎?
還是少了什麼東西?
我不知道這個程式你從哪裡抄來的...

看更多先前的回應...收起先前的回應...
narumi iT邦新手 5 級 ‧ 2018-12-17 15:07:38 檢舉

網頁的表單及上傳檔案的功能是可以正常操作的。
而C#的程式是查GOOGLE老師東一點西一點打出來的TAT
目前傳送字串這個應該是解開了,但如何字串加檔案一定傳上去就如同網頁功能同樣的結果現在在頭痛這個。。。

小魚 iT邦大師 1 級 ‧ 2018-12-17 15:13:25 檢舉
  1. 你是用 ASP.NET 嗎?
  2. 看不到 submit_Click_1 是在哪呼叫的
  3. 看不懂日文...
narumi iT邦新手 5 級 ‧ 2018-12-17 15:15:16 檢舉

原網頁原始碼應該是ASP。
SUBMIT是我在用C#的WINFROM在實作時建立出的按鍵。
我可以幫你翻譯!

小魚 iT邦大師 1 級 ‧ 2018-12-17 20:46:39 檢舉

WinForm, 所以你到底是要用WinForm還是要用WebForm ?

小魚 iT邦大師 1 級 ‧ 2018-12-17 20:52:07 檢舉

我大概知道你想做什麼了,
如果你是要POST資料過去,
你可以查一下 C# 爬蟲,
至於上傳檔案我沒有這樣做過,
或許可以試著用MVC的HttpPostedFileBase.

4
攻城屍
iT邦新手 4 級 ‧ 2018-12-18 09:54:04

原文:[C#] 使用 HttpClient 上傳檔案至伺服器

這邊我使用的方法是 HttpClientMultipartFormDataContent 做搭配,MultipartFormDataContent 會自動將 ContentType 設為 multipart/form-data,所以無需再特別設定。

HttpClient hc = new HttpClient();

string url = "http://localhost:63995/Home/Index";
string fileName = "Dapper.XML";
string filePathName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Dapper.XML");
string contentType = MimeMapping.GetMimeMapping(fileName);
string stringResult = null;

using (var content = new MultipartFormDataContent())
{
    content.Add(new StringContent("aaa", Encoding.UTF8), "Field_Text_1");
    content.Add(new StringContent("bbb", Encoding.UTF8), "Field_Text_2");

    Stream fileStream = File.OpenRead(fileName);
    StreamContent streamContent = new StreamContent(fileStream);
    streamContent.Headers.Add("Content-Type", contentType);

    content.Add(streamContent, "Field_File_1", fileName);

    var postResult = await hc.PostAsync(url, content);
    stringResult = await postResult.Content.ReadAsStringAsync();
}

return stringResult;

原來有現成的類別可以用~

我要發表回答

立即登入回答