SORU
20 EKİM 2008, PAZARTESİ


C parçalı formlar# client

C bir php uygulamasında bir form doldurmak için çalışıyorum# client (Outlook eklenti). Fiddler php uygulama içinde özgün istek görürdüm ve çok parçalı form/form olarak gönderilir. Ne yazık ki .Net formlar bir dosya yüklemek için tek bir yöntem var WebClient () bu tür desteği ile gelmiyor. Kimseye bir kütüphane olduğunu ya da bunu başarmak için bazı kod var mı? Farklı değerler ve (ama sadece bazen) bir dosya ayrıca post etmek istiyorum.

Yardımlarınız için teşekkürler, Sebastian

CEVAP
20 NİSAN 2009, PAZARTESİ


Cevaplar için teşekkürler, herkes! Geçenlerde iş için bu almak zorunda kaldı ve ağır önerilerinizi kullanılır. Ancak, beklendiği gibi işe yaramadı zor parçaları bir çift, çoğunlukla aslında dosya soruyu önemli bir parçası olan) de dahil olmak üzere yapmak zorunda vardı. Zaten cevaplar burada var, ama bu gelecekte birilerine faydası (bu online olarak çok net bir örnek bulamadım) olabilir diye düşünüyorum. Biraz daha açıklar 6**.

Temelde, ben ilk denedim pas içinde dosya olarak bir veri UTF8 kodlanmış dize, ama ben ile ilgili sorunlar yaşıyorsanız, kodlama dosyaları (işe yaradı güzel bir düz metin dosyası, ama ne zaman karşıya bir Word Belgesi, örneğin, kurtarmaya çalıştım dosya oldu geçti üzerinden ilan formunu doldurunuz.Files[0].() Farklı kaydet, Word'de dosya açma düzgün. işe yaramadı Eğer dosya doğrudan veri Akışı (bir StringBuilder yerine) kullanarak yazarsın, beklendiği gibi çalıştı bulundu. Ayrıca, anlamak benim için daha kolay yapılan değişiklikleri bir çift yaptım.

Bu arada, Multipart Forms Request for Comments W3C Recommendation for mulitpart/form-data herkes belirtimi için bir başvuru olması halinde yararlı kaynakların bir çift.

WebHelpers sınıf biraz küçük olduğu için değiştirdim ve basit arayüzler var, şimdi FormUpload denir. Eğer geçiş FormUpload.FileParameter iletebilirsiniz byte[] içeriği ile birlikte bir dosya adını ve içerik türü ve geçersen bir dize, tedavi olarak standart ad/değer kombinasyonu.

Burada FormUpload sınıfı:

// 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\n"), 0, encoding.GetByteCount("\r\n"));

            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\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n",
                    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\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{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\n--"   boundary   "--\r\n";
        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;
        }
    }
}

Burada bir dosya ve birkaç normal bir post parametreleri yükler çağıran kodu:

// Read file data
FileStream fs = new FileStream("c:\\people.doc", FileMode.Open, FileAccess.Read);
byte[] data = new byte[fs.Length];
fs.Read(data, 0, data.Length);
fs.Close();

// Generate post objects
Dictionary<string, object> postParameters = new Dictionary<string, object>();
postParameters.Add("filename", "People.doc");
postParameters.Add("fileformat", "doc");
postParameters.Add("file", new FormUpload.FileParameter(data, "People.doc", "application/msword"));

// Create request and receive response
string postURL = "http://localhost";
string userAgent = "Someone";
HttpWebResponse webResponse = FormUpload.MultipartFormDataPost(postURL, userAgent, postParameters);

// Process response
StreamReader responseReader = new StreamReader(webResponse.GetResponseStream());
string fullResponse = responseReader.ReadToEnd();
webResponse.Close();
Response.Write(fullResponse);

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • FRED

    FRED

    1 EKİM 2005
  • Louis C.K.

    Louis C.K.

    18 HAZİRAN 2006
  • sonia989

    sonia989

    26 EKİM 2006