来自C#客户端的多部分表单
我正在尝试从C#客户端(Outlook addin)在php应用程序中填写表单。我使用Fiddler查看php应用程序中的原始请求,表单以多部分/表单的形式传输。不幸的是.Net不支持这种类型的表单(WebClient只有一种上传文件的方法)。 有人知道一个库或者有一些代码来实现这一点吗?我想发布不同的值,并另外(但有时)发布一个文件 谢谢你的帮助,来自C#客户端的多部分表单,c#,http,multipartform-data,C#,Http,Multipartform Data,我正在尝试从C#客户端(Outlook addin)在php应用程序中填写表单。我使用Fiddler查看php应用程序中的原始请求,表单以多部分/表单的形式传输。不幸的是.Net不支持这种类型的表单(WebClient只有一种上传文件的方法)。 有人知道一个库或者有一些代码来实现这一点吗?我想发布不同的值,并另外(但有时)发布一个文件 谢谢你的帮助, Sebastian这是从我编写的一些示例代码中剪切和粘贴而来的,希望它能提供一些基础知识。目前只支持文件数据和表单数据 public class
Sebastian这是从我编写的一些示例代码中剪切和粘贴而来的,希望它能提供一些基础知识。目前只支持文件数据和表单数据
public class PostData
{
private List<PostDataParam> m_Params;
public List<PostDataParam> Params
{
get { return m_Params; }
set { m_Params = value; }
}
public PostData()
{
m_Params = new List<PostDataParam>();
// Add sample param
m_Params.Add(new PostDataParam("email", "MyEmail", PostDataParamType.Field));
}
/// <summary>
/// Returns the parameters array formatted for multi-part/form data
/// </summary>
/// <returns></returns>
public string GetPostData()
{
// Get boundary, default is --AaB03x
string boundary = ConfigurationManager.AppSettings["ContentBoundary"].ToString();
StringBuilder sb = new StringBuilder();
foreach (PostDataParam p in m_Params)
{
sb.AppendLine(boundary);
if (p.Type == PostDataParamType.File)
{
sb.AppendLine(string.Format("Content-Disposition: file; name=\"{0}\"; filename=\"{1}\"", p.Name, p.FileName));
sb.AppendLine("Content-Type: text/plain");
sb.AppendLine();
sb.AppendLine(p.Value);
}
else
{
sb.AppendLine(string.Format("Content-Disposition: form-data; name=\"{0}\"", p.Name));
sb.AppendLine();
sb.AppendLine(p.Value);
}
}
sb.AppendLine(boundary);
return sb.ToString();
}
}
public enum PostDataParamType
{
Field,
File
}
public class PostDataParam
{
public PostDataParam(string name, string value, PostDataParamType type)
{
Name = name;
Value = value;
Type = type;
}
public string Name;
public string FileName;
public string Value;
public PostDataParamType Type;
}
希望这是清楚的,我已经从一些来源剪切和粘贴,以使其更整洁。基于dnolans示例,这是我实际可以使用的版本(边界有一些错误,未设置编码):-) 要发送数据,请执行以下操作:
HttpWebRequest oRequest = null;
oRequest = (HttpWebRequest)HttpWebRequest.Create("http://you.url.here");
oRequest.ContentType = "multipart/form-data; boundary=" + PostData.boundary;
oRequest.Method = "POST";
PostData pData = new PostData();
Encoding encoding = Encoding.UTF8;
Stream oStream = null;
/* ... set the parameters, read files, etc. IE:
pData.Params.Add(new PostDataParam("email", "example@example.com", PostDataParamType.Field));
pData.Params.Add(new PostDataParam("fileupload", "filename.txt", "filecontents" PostDataParamType.File));
*/
byte[] buffer = encoding.GetBytes(pData.GetPostData());
oRequest.ContentLength = buffer.Length;
oStream = oRequest.GetRequestStream();
oStream.Write(buffer, 0, buffer.Length);
oStream.Close();
HttpWebResponse oResponse = (HttpWebResponse)oRequest.GetResponse();
PostData类应该如下所示:
public class PostData
{
// Change this if you need to, not necessary
public static string boundary = "AaB03x";
private List<PostDataParam> m_Params;
public List<PostDataParam> Params
{
get { return m_Params; }
set { m_Params = value; }
}
public PostData()
{
m_Params = new List<PostDataParam>();
}
/// <summary>
/// Returns the parameters array formatted for multi-part/form data
/// </summary>
/// <returns></returns>
public string GetPostData()
{
StringBuilder sb = new StringBuilder();
foreach (PostDataParam p in m_Params)
{
sb.AppendLine("--" + boundary);
if (p.Type == PostDataParamType.File)
{
sb.AppendLine(string.Format("Content-Disposition: file; name=\"{0}\"; filename=\"{1}\"", p.Name, p.FileName));
sb.AppendLine("Content-Type: application/octet-stream");
sb.AppendLine();
sb.AppendLine(p.Value);
}
else
{
sb.AppendLine(string.Format("Content-Disposition: form-data; name=\"{0}\"", p.Name));
sb.AppendLine();
sb.AppendLine(p.Value);
}
}
sb.AppendLine("--" + boundary + "--");
return sb.ToString();
}
}
public enum PostDataParamType
{
Field,
File
}
public class PostDataParam
{
public PostDataParam(string name, string value, PostDataParamType type)
{
Name = name;
Value = value;
Type = type;
}
public PostDataParam(string name, string filename, string value, PostDataParamType type)
{
Name = name;
Value = value;
FileName = filename;
Type = type;
}
public string Name;
public string FileName;
public string Value;
public PostDataParamType Type;
}
公共类PostData
{
//如果需要,请更改此选项,无需更改
公共静态字符串边界=“AaB03x”;
私有列表m_参数;
公共列表参数
{
获取{return m_Params;}
设置{m_Params=value;}
}
公共PostData()
{
m_Params=新列表();
}
///
///返回为多部分/表单数据格式化的参数数组
///
///
公共字符串GetPostData()
{
StringBuilder sb=新的StringBuilder();
foreach(m_参数中的PostDataParam p)
{
sb.附加线(“-”+边界);
if(p.Type==PostDataParamType.File)
{
sb.AppendLine(string.Format(“内容配置:文件;名称=\”{0}\“文件名=\”{1}\”,p.name,p.filename));
sb.AppendLine(“内容类型:应用程序/八位字节流”);
(某人);
sb.附加线(p.值);
}
其他的
{
sb.AppendLine(string.Format(“内容处置:表单数据;名称=\”{0}\”,p.name));
(某人);
sb.附加线(p.值);
}
}
sb.附录行(“-”+边界+“-”);
使某人返回字符串();
}
}
公共枚举PostDataParamType
{
领域
文件
}
公共类PostDataParam
{
公共PostDataParam(字符串名称、字符串值、PostDataParamType类型)
{
名称=名称;
价值=价值;
类型=类型;
}
公共PostDataParam(字符串名称、字符串文件名、字符串值、PostDataParamType类型)
{
名称=名称;
价值=价值;
FileName=文件名;
类型=类型;
}
公共字符串名称;
公共字符串文件名;
公共字符串值;
公共PostDataParamType类型;
}
我需要模拟浏览器登录网站以获得登录cookie,而登录表单是多部分/表单数据
我从其他答案中提取了一些线索,然后试图让我自己的方案发挥作用。经过了一些令人沮丧的尝试和错误之后,它才正常工作,但代码如下:
public static class WebHelpers
{
/// <summary>
/// Post the data as a multipart form
/// </summary>
public static HttpWebResponse MultipartFormDataPost(string postUrl, string userAgent, Dictionary<string, string> values)
{
string formDataBoundary = "---------------------------" + WebHelpers.RandomHexDigits(12);
string contentType = "multipart/form-data; boundary=" + formDataBoundary;
string formData = WebHelpers.MakeMultipartForm(values, formDataBoundary);
return WebHelpers.PostForm(postUrl, userAgent, contentType, formData);
}
/// <summary>
/// Post a form
/// </summary>
public static HttpWebResponse PostForm(string postUrl, string userAgent, string contentType, string formData)
{
HttpWebRequest request = WebRequest.Create(postUrl) as HttpWebRequest;
if (request == null)
{
throw new NullReferenceException("request is not a http request");
}
// Add these, as we're doing a POST
request.Method = "POST";
request.ContentType = contentType;
request.UserAgent = userAgent;
request.CookieContainer = new CookieContainer();
// We need to count how many bytes we're sending.
byte[] postBytes = Encoding.UTF8.GetBytes(formData);
request.ContentLength = postBytes.Length;
using (Stream requestStream = request.GetRequestStream())
{
// Push it out there
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
}
return request.GetResponse() as HttpWebResponse;
}
/// <summary>
/// Generate random hex digits
/// </summary>
public static string RandomHexDigits(int count)
{
Random random = new Random();
StringBuilder result = new StringBuilder();
for (int i = 0; i < count; i++)
{
int digit = random.Next(16);
result.AppendFormat("{0:x}", digit);
}
return result.ToString();
}
/// <summary>
/// Turn the key and value pairs into a multipart form
/// </summary>
private static string MakeMultipartForm(Dictionary<string, string> values, string boundary)
{
StringBuilder sb = new StringBuilder();
foreach (var pair in values)
{
sb.AppendFormat("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}\r\n", boundary, pair.Key, pair.Value);
}
sb.AppendFormat("--{0}--\r\n", boundary);
return sb.ToString();
}
}
}
谢谢大家的回答!我最近不得不让它工作,并且大量使用了你的建议。然而,有几个棘手的部分并没有像预期的那样工作,主要是与实际包含文件有关(这是问题的一个重要部分)。这里已经有很多答案,但我认为这可能对将来的人有用(我在网上找不到很多明确的例子)。我想这能解释得更清楚一点 基本上,我第一次尝试将文件数据作为UTF8编码的字符串传递,但在编码文件时遇到了问题(对于纯文本文件来说,它工作得很好,但在上载Word文档时,例如,如果我尝试使用Request.files[0].SaveAs()保存传递到发布表单的文件,在Word中打开文件无法正常工作。我发现,如果您直接使用流(而不是StringBuilder)编写文件数据,它会按预期工作。此外,我做了一些修改,使我更容易理解 顺便说一下,和是一些有用的资源,以防任何人需要规范的参考 我将WebHelpers类更改为更小一些,并且具有更简单的接口,现在它被称为
FormUpload
。如果传递FormUpload.FileParameter
,则可以传递byte[]内容以及文件名和内容类型,如果传递字符串,则将其视为标准名称/值组合
这是FormUpload类:
// 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;
}
}
}
// 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);
//在C#中实现多部分/表单数据发布http://www.ietf.org/rfc/rfc2388.txt
// http://www.briangrinstead.com/blog/multipart-form-post-in-c
公共静态类FormUpload
{
私有静态只读编码编码=Encoding.UTF8;
公共静态HttpWebResponse MultipartFormDataPost(字符串姿势、字符串用户代理、字典后参数)
{
string formDataBoundary=string.Format(“------------{0:N}”,Guid.NewGuid());
string contentType=“多部分/表单数据;边界=“+formDataBoundary;
byte[]formData=GetMultipartFormData(后参数,formDataBoundary);
返回PostForm(postrl、userAgent、contentType、formData);
}
私有静态HttpWebResponse PostForm(字符串postrl、字符串userAgent、字符串contentType、字节[]formData)
{
HttpWebRequest-request=WebRequest.Create(postrl)为HttpWebRequest;
if(请求==null)
{
抛出新的NullReferenceException(“请求不是http请求”);
}
//设置请求属性。
request.Method=“POST”;
request.ContentType=ContentType;
request.UserAgent=UserAgent;
request.CookieContainer=新的CookieContainer();
request.ContentLength=formData.Length;
// 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;
}
}
}
// 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);
//This URL not exist, it's only an example.
string url = "http://myBox.s3.amazonaws.com/";
//Instantiate new CustomWebRequest class
CustomWebRequest wr = new CustomWebRequest(url);
//Set values for parameters
wr.ParamsCollection.Add(new ParamsStruct("key", "${filename}"));
wr.ParamsCollection.Add(new ParamsStruct("acl", "public-read"));
wr.ParamsCollection.Add(new ParamsStruct("success_action_redirect", "http://www.yahoo.com"));
wr.ParamsCollection.Add(new ParamsStruct("x-amz-meta-uuid", "14365123651274"));
wr.ParamsCollection.Add(new ParamsStruct("x-amz-meta-tag", ""));
wr.ParamsCollection.Add(new ParamsStruct("AWSAccessKeyId", "zzzz"));
wr.ParamsCollection.Add(new ParamsStruct("Policy", "adsfadsf"));
wr.ParamsCollection.Add(new ParamsStruct("Signature", "hH6lK6cA="));
//For file type, send the inputstream of selected file
StreamReader sr = new StreamReader(@"file.txt");
wr.ParamsCollection.Add(new ParamsStruct("file", sr, ParamsStruct.ParamType.File, "file.txt"));
wr.PostData();
System.Net.ServicePointManager.Expect100Continue = false;
--THEBOUNDARY
--THEBOUNDARY--
namespace WindowsFormsApplication1
{
public static class FormUpload
{
private static string NewDataBoundary()
{
Random rnd = new Random();
string formDataBoundary = "";
while (formDataBoundary.Length < 15)
{
formDataBoundary = formDataBoundary + rnd.Next();
}
formDataBoundary = formDataBoundary.Substring(0, 15);
formDataBoundary = "-----------------------------" + formDataBoundary;
return formDataBoundary;
}
public static HttpWebResponse MultipartFormDataPost(string postUrl, IEnumerable<Cookie> cookies, Dictionary<string, string> postParameters)
{
string boundary = NewDataBoundary();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(postUrl);
// Set up the request properties
request.Method = "POST";
request.ContentType = "multipart/form-data; boundary=" + boundary;
request.UserAgent = "PhasDocAgent 1.0";
request.CookieContainer = new CookieContainer();
foreach (var cookie in cookies)
{
request.CookieContainer.Add(cookie);
}
#region WRITING STREAM
using (Stream formDataStream = request.GetRequestStream())
{
foreach (var param in postParameters)
{
if (param.Value.StartsWith("file://"))
{
string filepath = param.Value.Substring(7);
// 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,
Path.GetFileName(filepath) ?? param.Key,
MimeTypes.GetMime(filepath));
formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, header.Length);
// Write the file data directly to the Stream, rather than serializing it to a string.
byte[] buffer = new byte[2048];
FileStream fs = new FileStream(filepath, FileMode.Open);
for (int i = 0; i < fs.Length; )
{
int k = fs.Read(buffer, 0, buffer.Length);
if (k > 0)
{
formDataStream.Write(buffer, 0, k);
}
i = i + k;
}
fs.Close();
}
else
{
string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}\r\n",
boundary,
param.Key,
param.Value);
formDataStream.Write(Encoding.UTF8.GetBytes(postData), 0, postData.Length);
}
}
// Add the end of the request
byte[] footer = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
formDataStream.Write(footer, 0, footer.Length);
request.ContentLength = formDataStream.Length;
formDataStream.Close();
}
#endregion
return request.GetResponse() as HttpWebResponse;
}
}
}
formDataStream.Write(encoding.GetBytes(postData), 0, postData.Length);
byte[] aPostData=encoding.GetBytes(postData);
formDataStream.Write(aPostData, 0, aPostData.Length);
/// <summary>
/// Sending file via multipart\form-data
/// </summary>
/// <param name="url">URL for send</param>
/// <param name="file">Local file path</param>
/// <param name="paramName">Request file param</param>
/// <param name="contentType">Content-Type file headr</param>
/// <param name="nvc">Additional post params</param>
private static string httpUploadFile(string url, string file, string paramName, string contentType, NameValueCollection nvc)
{
//delimeter
var boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
//creating request
var wr = (HttpWebRequest)WebRequest.Create(url);
wr.ContentType = "multipart/form-data; boundary=" + boundary;
wr.Method = "POST";
wr.KeepAlive = true;
//sending request
using(var requestStream = wr.GetRequestStream())
{
using (var requestWriter = new StreamWriter(requestStream, Encoding.UTF8))
{
//params
const string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
foreach (string key in nvc.Keys)
{
requestWriter.Write(boundary);
requestWriter.Write(String.Format(formdataTemplate, key, nvc[key]));
}
requestWriter.Write(boundary);
//file header
const string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
requestWriter.Write(String.Format(headerTemplate, paramName, file, contentType));
//file content
using (var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read))
{
fileStream.CopyTo(requestStream);
}
requestWriter.Write("\r\n--" + boundary + "--\r\n");
}
}
//reading response
try
{
using (var wresp = (HttpWebResponse)wr.GetResponse())
{
if (wresp.StatusCode == HttpStatusCode.OK)
{
using (var responseStream = wresp.GetResponseStream())
{
if (responseStream == null)
return null;
using (var responseReader = new StreamReader(responseStream))
{
return responseReader.ReadToEnd();
}
}
}
throw new ApplicationException("Error while upload files. Server status code: " + wresp.StatusCode.ToString());
}
}
catch (Exception ex)
{
throw new ApplicationException("Error while uploading file", ex);
}
}
using System;
using System.IO;
using System.Net.Http;
namespace HttpClientTest
{
class Program
{
static void Main(string[] args)
{
var client = new HttpClient();
var content = new MultipartFormDataContent();
content.Add(new StreamContent(File.Open("../../Image1.png", FileMode.Open)), "Image", "Image.png");
content.Add(new StringContent("Place string content here"), "Content-Id in the HTTP");
var result = client.PostAsync("https://hostname/api/Account/UploadAvatar", content);
Console.WriteLine(result.Result.ToString());
}
}
}