/// <summary> /// Constructor.</summary> /// <param name="request"> /// The request to be used for the form data submission. This class automatically sets several fields which should not /// be modified by the caller afterwards. These are: Method, ContentType. You MUST NOT call <see /// cref="HttpWebRequest.GetRequestStream()"/> or <see cref="HttpWebRequest.GetResponse()"/> on this request. You may /// modify request headers until the first call to an Add* method.</param> public MultipartFormDataHelper(HttpWebRequest request) { if (request == null) { throw new ArgumentNullException(nameof(request)); } _request = request; var boundary = Rnd.NextBytes(15).ToHex(); _bytesBoundary = ("--" + boundary + "\r\n").ToUtf8(); _bytesBoundaryLast = ("--" + boundary + "--\r\n").ToUtf8(); _request.ContentType = "multipart/form-data; boundary=" + boundary; _request.Method = "POST"; }
/// <summary> /// Performs a POST request with the body consisting of a series of key-value arguments, encoded in the /// <c>multipart/form-data</c> format.</summary> /// <param name="url"> /// The URL of the request. If the URL does not begin with <c>http://</c> or <c>https://</c>, it is automatically /// prepended with <see cref="RootUrl"/>.</param> /// <param name="args"> /// The arguments to pass with the POST request. Null values are allowed and ignored.</param> /// <returns> /// The response received from the server.</returns> /// <remarks> /// Choose this format for requests that need to contain file uploads.</remarks> /// <seealso cref="Post(string,HArg[])"/> public HResponse PostFormdata(string url, params HArg[] args) { if (args == null) { args = new HArg[0]; } var invalid = args.Where(a => a != null).FirstOrDefault(a => !a.Valid); if (invalid != null) { throw new ArgumentException("args", "The argument with name '{0}' is not valid.".Fmt(invalid.Name)); } string boundary = Rnd.NextBytes(20).ToHex(); var ms = new MemoryStream(300 + args.Where(a => a != null).Sum(a => 30 + a.Name.Length + (a.FileContent == null ? a.Value.Length : a.FileContent.Length))); var sw = new StreamWriter(ms); sw.AutoFlush = true; foreach (var arg in args.Where(a => a != null)) { if (arg.FileContent == null) { sw.WriteLine("--" + boundary); sw.WriteLine(@"Content-Disposition: form-data; name=""" + arg.Name + @""""); sw.WriteLine(); sw.WriteLine(arg.Value); } else { sw.WriteLine("--" + boundary); sw.WriteLine(@"Content-Disposition: form-data; name=""" + arg.Name + @"""; filename=""" + arg.FileName + @""""); sw.WriteLine(@"Content-Type: " + arg.FileContentType); sw.WriteLine(); ms.Write(arg.FileContent); sw.WriteLine(); } } sw.WriteLine("--" + boundary + "--"); return(Post(url, ms.ToArray(), "multipart/form-data; boundary=" + boundary)); }