C # के साथ HTTP POST के माध्यम से एक फ़ाइल भेजें


95

मैं खोज कर रहा हूं और उसके आसपास पढ़ रहा हूं और वास्तव में उपयोगी कुछ भी ठीक नहीं कर सका।

मैं एक छोटा सी # जीत ऐप लिख रहा हूं जो उपयोगकर्ता को एफ़टीपी द्वारा नहीं, बल्कि POST का उपयोग करके HTTP द्वारा वेब सर्वर पर फाइल भेजने की अनुमति देता है। इसे वेब फॉर्म की तरह समझें लेकिन विंडोज़ एप्लिकेशन पर चल रहा है।

मेरे पास अपना HttpWebRequest ऑब्जेक्ट कुछ इस तरह का उपयोग करके बनाया गया है

HttpWebRequest req = WebRequest.Create(uri) as HttpWebRequest 

और यह भी सेट Method, ContentTypeऔर ContentLengthगुण। लेकिन मैं दूर जा सकता है thats।

यह मेरे कोड का टुकड़ा है:

HttpWebRequest req = WebRequest.Create(uri) as HttpWebRequest;
req.KeepAlive = false;
req.Method = "POST";
req.Credentials = new NetworkCredential(user.UserName, user.UserPassword);
req.PreAuthenticate = true;
req.ContentType = file.ContentType;
req.ContentLength = file.Length;
HttpWebResponse response = null;

try
{
    response = req.GetResponse() as HttpWebResponse;
}
catch (Exception e) 
{
}

तो मेरा सवाल मूल रूप से है कि मैं HTTP POST के माध्यम से C # के साथ एक फ़ी (पाठ फ़ाइल, छवि, ऑडियो, आदि) कैसे भेज सकता हूं।

धन्यवाद!


जवाबों:


112

.NET 4.5 (या .NET 4.0 का उपयोग Microsoft.Net.Hutp पैकेज को NuGet से जोड़कर ) करने से फ़ॉर्म अनुरोधों को अनुकरण करने का एक आसान तरीका है। यहाँ एक उदाहरण है:

private async Task<System.IO.Stream> Upload(string actionUrl, string paramString, Stream paramFileStream, byte [] paramFileBytes)
{
    HttpContent stringContent = new StringContent(paramString);
    HttpContent fileStreamContent = new StreamContent(paramFileStream);
    HttpContent bytesContent = new ByteArrayContent(paramFileBytes);
    using (var client = new HttpClient())
    using (var formData = new MultipartFormDataContent())
    {
        formData.Add(stringContent, "param1", "param1");
        formData.Add(fileStreamContent, "file1", "file1");
        formData.Add(bytesContent, "file2", "file2");
        var response = await client.PostAsync(actionUrl, formData);
        if (!response.IsSuccessStatusCode)
        {
            return null;
        }
        return await response.Content.ReadAsStreamAsync();
    }
}

8
यदि संभव हो तो इस पद्धति को कॉल करने का एक सरल उदाहरण दिखा सकता है?
जैकब 365

10
whats paramString पैरामीटर?
एरॉन ओटज़ैप

2
धन्यवाद, बहुत व्यापक उदाहरण! @eranotzap paramString भेजने के लिए परम का वास्तविक मूल्य है। करने के लिए तीसरा तर्क form.Addहै वैकल्पिक और फ़ाइलों के लिए ही उपयोगी।
स्टॉकब्रीक

1
@ लियम, मैं पूरी तरह से सहमत हूं। चीजों को सरल रखने के लिए मेरे 2013 के उत्तर से एसिंक्स कोड हटा दिया गया था। इसे async मेथड में बदलना मेरी टूडू लिस्ट पर रहा है क्योंकि इस बिंदु पर अधिकांश C # डेवलपर्स को इसके साथ सहज होना चाहिए।
जोशकोड्स

1
@ अम्मर, ऐसा नहीं है कि मैं इससे वाकिफ हूं, मुझे लगता है कि आपको फाइल को एक स्ट्रीम या बाइट [] में पढ़ना होगा और क्रमशः स्ट्रीमकंट या बाइटअरेकॉन्टेंट का उपयोग करना होगा।
जोशकोड्स

51

केवल कच्ची फ़ाइल भेजने के लिए :

using(WebClient client = new WebClient()) {
    client.UploadFile(address, filePath);
}

यदि आप एक के साथ एक ब्राउज़र फ़ॉर्म का अनुकरण करना चाहते हैं <input type="file"/>, तो यह कठिन है। मल्टीपार्ट / फॉर्म-डेटा उत्तर के लिए इस उत्तर को देखें ।


(आप निश्चित रूप से शीर्ष लेख / साख / आदि के रूप में सामान्य जोड़ सकते हैं)
मार्क Gravell

1
धन्यवाद, मैंने इसे कुछ सरल के साथ प्रयोग किया है और मैंने काम नहीं किया है। अब, जैसा कि आप कहते हैं, मुझे किसी ब्राउज़र इनपुट फ़ाइल का अनुकरण करने की आवश्यकता है, किसी तरह इस <intput प्रकार = "फ़ाइल" नाम "userFile" />।
गबित्जू

1
मैंने उपरोक्त कोड का उपयोग किया है और त्रुटि मिली है: उपयोगकर्ता कोड द्वारा तर्क अपवाद को अनहैंड कर दिया गया था: {"URI समर्थित नहीं हैं।"}। मैं यह कैसे कर सकता हूँ? संरक्षित शून्य Page_Load (ऑब्जेक्ट प्रेषक, EventArgs e) {स्ट्रिंग पता = "http: www.testproject.com/SavedFiles"; string filepath = @ "D: \ test \ FileOperations \ testfile.txt"; उपयोग (WebClient ग्राहक = नया WebClient ()) {client.UploadFile (पता, फ़ाइलपथ); }}
सुधा

1
@ सुधा क्या आपने वास्तविक वेब पते का उपयोग करने की कोशिश की है? http://www.testproject.com/SavedFiles- ध्यान दें//
मार्क Gravell

7

मेरे लिए client.UploadFileअभी भी सामग्री को मल्टीपार्ट अनुरोध में लपेटा गया है, इसलिए मुझे इसे इस तरह करना था:

using (WebClient client = new WebClient())
{
    client.Headers.Add("Content-Type", "application/octet-stream");
    using (Stream fileStream = File.OpenRead(filePath))
    using (Stream requestStream = client.OpenWrite(new Uri(fileUploadUrl), "POST"))
    {
        fileStream.CopyTo(requestStream);
    }
}

5

मुझे एक ही समस्या मिली थी और इस कोड ने इस समस्या पर पूरी तरह से जवाब दिया:

//Identificate separator
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
//Encoding
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");

//Creation and specification of the request
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url); //sVal is id for the webService
wr.ContentType = "multipart/form-data; boundary=" + boundary;
wr.Method = "POST";
wr.KeepAlive = true;
wr.Credentials = System.Net.CredentialCache.DefaultCredentials;

string sAuthorization = "login:password";//AUTHENTIFICATION BEGIN
byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(sAuthorization);
string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
wr.Headers.Add("Authorization: Basic " + returnValue); //AUTHENTIFICATION END
Stream rs = wr.GetRequestStream();


string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}"; //For the POST's format

//Writting of the file
rs.Write(boundarybytes, 0, boundarybytes.Length);
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(Server.MapPath("questions.pdf"));
rs.Write(formitembytes, 0, formitembytes.Length);

rs.Write(boundarybytes, 0, boundarybytes.Length);

string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
string header = string.Format(headerTemplate, "file", "questions.pdf", contentType);
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
rs.Write(headerbytes, 0, headerbytes.Length);

FileStream fileStream = new FileStream(Server.MapPath("questions.pdf"), FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[4096];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
    rs.Write(buffer, 0, bytesRead);
}
fileStream.Close();

byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
rs.Write(trailer, 0, trailer.Length);
rs.Close();
rs = null;

WebResponse wresp = null;
try
{
    //Get the response
    wresp = wr.GetResponse();
    Stream stream2 = wresp.GetResponseStream();
    StreamReader reader2 = new StreamReader(stream2);
    string responseData = reader2.ReadToEnd();
}
catch (Exception ex)
{
    string s = ex.Message;
}
finally
{
    if (wresp != null)
    {
        wresp.Close();
        wresp = null;
    }
    wr = null;
}

आप डेटा कैसे प्राप्त करते हैं और फ़ाइल को दूसरे छोर पर डिस्क पर सहेजते हैं?
कुमारहर्ष

3

आपको अपनी फ़ाइल अनुरोध स्ट्रीम में लिखने की आवश्यकता है:

using (var reqStream = req.GetRequestStream()) 
{    
    reqStream.Write( ... ) // write the bytes of the file
}

1

बाइट सरणियों से फ़ाइलों को पोस्ट करने के लिए:

private static string UploadFilesToRemoteUrl(string url, IList<byte[]> files, NameValueCollection nvc) {

        string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");

        var request = (HttpWebRequest) WebRequest.Create(url);
        request.ContentType = "multipart/form-data; boundary=" + boundary;
        request.Method = "POST";
        request.KeepAlive = true;
        var postQueue = new ByteArrayCustomQueue();

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

        foreach (string key in nvc.Keys) {
            var formitem = string.Format(formdataTemplate, key, nvc[key]);
            var formitembytes = Encoding.UTF8.GetBytes(formitem);
            postQueue.Write(formitembytes);
        }

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

        var i = 0;
        foreach (var file in files) {
            var header = string.Format(headerTemplate, "file" + i, "file" + i + ".zip");
            var headerbytes = Encoding.UTF8.GetBytes(header);
            postQueue.Write(headerbytes);
            postQueue.Write(file);
            i++;
        }

        postQueue.Write(Encoding.UTF8.GetBytes("\r\n--" + boundary + "--"));

        request.ContentLength = postQueue.Length;

        using (var requestStream = request.GetRequestStream()) {
            postQueue.CopyToStream(requestStream);
            requestStream.Close();
        }

        var webResponse2 = request.GetResponse();

        using (var stream2 = webResponse2.GetResponseStream())
        using (var reader2 = new StreamReader(stream2)) {

            var res =  reader2.ReadToEnd();
            webResponse2.Close();
            return res;
        }
    }

public class ByteArrayCustomQueue {

    private LinkedList<byte[]> arrays = new LinkedList<byte[]>();

    /// <summary>
    /// Writes the specified data.
    /// </summary>
    /// <param name="data">The data.</param>
    public void Write(byte[] data) {
        arrays.AddLast(data);
    }

    /// <summary>
    /// Gets the length.
    /// </summary>
    /// <value>
    /// The length.
    /// </value>
    public int Length { get { return arrays.Sum(x => x.Length); } }

    /// <summary>
    /// Copies to stream.
    /// </summary>
    /// <param name="requestStream">The request stream.</param>
    /// <exception cref="System.NotImplementedException"></exception>
    public void CopyToStream(Stream requestStream) {
        foreach (var array in arrays) {
            requestStream.Write(array, 0, array.Length);
        }
    }
}

1
     public string SendFile(string filePath)
            {
                WebResponse response = null;
                try
                {
                    string sWebAddress = "Https://www.address.com";

                    string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
                    byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
                    HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(sWebAddress);
                    wr.ContentType = "multipart/form-data; boundary=" + boundary;
                    wr.Method = "POST";
                    wr.KeepAlive = true;
                    wr.Credentials = System.Net.CredentialCache.DefaultCredentials;
                    Stream stream = wr.GetRequestStream();
                    string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";

                    stream.Write(boundarybytes, 0, boundarybytes.Length);
                    byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(filePath);
                    stream.Write(formitembytes, 0, formitembytes.Length);
                    stream.Write(boundarybytes, 0, boundarybytes.Length);
                    string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
                    string header = string.Format(headerTemplate, "file", Path.GetFileName(filePath), Path.GetExtension(filePath));
                    byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
                    stream.Write(headerbytes, 0, headerbytes.Length);

                    FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                    byte[] buffer = new byte[4096];
                    int bytesRead = 0;
                    while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                        stream.Write(buffer, 0, bytesRead);
                    fileStream.Close();

                    byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
                    stream.Write(trailer, 0, trailer.Length);
                    stream.Close();

                    response = wr.GetResponse();
                    Stream responseStream = response.GetResponseStream();
                    StreamReader streamReader = new StreamReader(responseStream);
                    string responseData = streamReader.ReadToEnd();
                    return responseData;
                }
                catch (Exception ex)
                {
                    return ex.Message;
                }
                finally
                {
                    if (response != null)
                        response.Close();
                }
            }

0

.NET 4.5 का उपयोग करके फॉर्म POST फ़ाइल अपलोड करने की कोशिश कर रहा है। ऊपर अधिकांश तरीकों की कोशिश की लेकिन कोई फायदा नहीं हुआ। यहाँ समाधान मिले https://www.c-sharpcorner.com/article/upload-any-file-using-http-post-multipart-form-data

लेकिन मैं उत्सुक नहीं हूं क्योंकि मुझे समझ नहीं आ रहा है कि हमें अभी भी इन सामान्य उपयोगों में निम्न स्तर की प्रोग्रामिंग से निपटने की आवश्यकता है (इसे फ्रेमवर्क द्वारा अच्छी तरह से संभाला जाना चाहिए)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.