Domanda

Qual è il modo più semplice per inviare una richiesta POST HTTP con un tipo di contenuto multipart / form-data da C #? Deve esserci un modo migliore che costruire la mia richiesta.

Il motivo per cui sto chiedendo è di caricare foto su Flickr usando questa API:

http://www.flickr.com/services/api/upload. API.html

È stato utile?

Soluzione

Prima di tutto, non c'è niente di sbagliato nella pura implementazione manuale dei comandi HTTP che usano il framework .Net. Tieni presente che si tratta di un framework e dovrebbe essere piuttosto generico.

In secondo luogo, penso che tu possa provare a cercare un'implementazione del browser in .Net. Ho visto questo , forse copre il problema che hai chiesto di. Oppure puoi semplicemente cercare " C # http put get post request " ;. Uno dei risultati porta a una libreria non gratuita che può essere utile ( Chilkat Http)

Se ti capita di scrivere il tuo framework di comandi HTTP su .Net - Penso che potremo divertirci tutti se lo condividi :-)

Altri suggerimenti

Se si utilizza .NET 4.5, utilizzare questo:

public string Upload(string url, NameValueCollection requestParameters, MemoryStream file)
        {

            var client = new HttpClient();
            var content = new MultipartFormDataContent();

            content.Add(new StreamContent(file));
            System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<string, string>> b = new List<KeyValuePair<string, string>>();
            b.Add(requestParameters);
            var addMe = new FormUrlEncodedContent(b);

            content.Add(addMe);
            var result = client.PostAsync(url, content);
            return result.Result.ToString();
        }

Altrimenti, in base alla risposta di Ryan, ho scaricato la libreria e l'ho modificata un po '.

  public class MimePart
        {
            NameValueCollection _headers = new NameValueCollection();
            byte[] _header;

            public NameValueCollection Headers
            {
                get { return _headers; }
            }

            public byte[] Header
            {
                get { return _header; }
            }

            public long GenerateHeaderFooterData(string boundary)
            {
                StringBuilder sb = new StringBuilder();

                sb.Append("--");
                sb.Append(boundary);
                sb.AppendLine();
                foreach (string key in _headers.AllKeys)
                {
                    sb.Append(key);
                    sb.Append(": ");
                    sb.AppendLine(_headers[key]);
                }
                sb.AppendLine();

                _header = Encoding.UTF8.GetBytes(sb.ToString());

                return _header.Length + Data.Length + 2;
            }

            public Stream Data { get; set; }
        }

        public string Upload(string url, NameValueCollection requestParameters, params MemoryStream[] files)
        {
            using (WebClient req = new WebClient())
            {
                List<MimePart> mimeParts = new List<MimePart>();

                try
                {
                    foreach (string key in requestParameters.AllKeys)
                    {
                        MimePart part = new MimePart();

                        part.Headers["Content-Disposition"] = "form-data; name=\"" + key + "\"";
                        part.Data = new MemoryStream(Encoding.UTF8.GetBytes(requestParameters[key]));

                        mimeParts.Add(part);
                    }

                    int nameIndex = 0;

                    foreach (MemoryStream file in files)
                    {
                        MimePart part = new MimePart();
                        string fieldName = "file" + nameIndex++;

                        part.Headers["Content-Disposition"] = "form-data; name=\"" + fieldName + "\"; filename=\"" + fieldName + "\"";
                        part.Headers["Content-Type"] = "application/octet-stream";

                        part.Data = file;

                        mimeParts.Add(part);
                    }

                    string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
                    req.Headers.Add(HttpRequestHeader.ContentType, "multipart/form-data; boundary=" + boundary);

                    long contentLength = 0;

                    byte[] _footer = Encoding.UTF8.GetBytes("--" + boundary + "--\r\n");

                    foreach (MimePart part in mimeParts)
                    {
                        contentLength += part.GenerateHeaderFooterData(boundary);
                    }

                    //req.ContentLength = contentLength + _footer.Length;

                    byte[] buffer = new byte[8192];
                    byte[] afterFile = Encoding.UTF8.GetBytes("\r\n");
                    int read;

                    using (MemoryStream s = new MemoryStream())
                    {
                        foreach (MimePart part in mimeParts)
                        {
                            s.Write(part.Header, 0, part.Header.Length);

                            while ((read = part.Data.Read(buffer, 0, buffer.Length)) > 0)
                                s.Write(buffer, 0, read);

                            part.Data.Dispose();

                            s.Write(afterFile, 0, afterFile.Length);
                        }

                        s.Write(_footer, 0, _footer.Length);
                        byte[] responseBytes = req.UploadData(url, s.ToArray());
                        string responseString = Encoding.UTF8.GetString(responseBytes);
                        return responseString;
                    }
                }
                catch
                {
                    foreach (MimePart part in mimeParts)
                        if (part.Data != null)
                            part.Data.Dispose();

                    throw;
                }
            }
        }

Non ho provato questo da solo, ma sembra che ci sia un modo integrato in C # per questo (anche se apparentemente non molto conosciuto ...):

private static HttpClient _client = null;

private static void UploadDocument()
{
    // Add test file 
    var httpContent = new MultipartFormDataContent();
    var fileContent = new ByteArrayContent(File.ReadAllBytes(@"File.jpg"));
    fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
    {
        FileName = "File.jpg"
    };

    httpContent.Add(fileContent);
    string requestEndpoint = "api/Post";

    var response = _client.PostAsync(requestEndpoint, httpContent).Result;

    if (response.IsSuccessStatusCode)
    {
        // ...
    }
    else
    {
        // Check response.StatusCode, response.ReasonPhrase
    }
}

Provalo e fammi sapere come va.

Cheers!

Ho avuto successo con il codice pubblicato su aspnetupload .com . Ho finito per creare la mia versione della loro libreria UploadHelper che è compatibile con il Compact Framework. Funziona bene, sembra fare esattamente ciò di cui hai bisogno.

La classe System.Net.WebClient potrebbe essere ciò che stai cercando. Controlla la documentazione per WebClient.UploadFile, dovrebbe consentire di caricare un file su una risorsa specificata tramite uno dei sovraccarichi UploadFile. Penso che questo sia il metodo che stai cercando di utilizzare per pubblicare i dati ...

Può essere usato come .... nota che questo è solo un codice di esempio non testato ...

WebClient webClient = new WebClient ();

webClient.UploadFile (" http://www.url.com/ReceiveUploadedFile.aspx " ;, " POST " ;, @ " c: \ myfile.txt ");

Ecco il riferimento MSDN se sei interessato.

http://msdn.microsoft.com /en-us/library/system.net.webclient.uploadfile.aspx

Spero che questo aiuti.

Normalmente trovo Fiddler di essere lo strumento migliore per quel lavoro. Molto facile da creare richieste e genera anche alcune delle intestazioni per te.

Fiddler - Come creare una richiesta

inserisci qui la descrizione dell'immagine

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top