【发布时间】:2014-02-25 00:51:03
【问题描述】:
我决定我的问题 here 并不是我真正想要做的 - 我需要发送的 XML 可能比我真正想要在 URI 中发送的要长得多。
这样做并不“感觉”正确,this 取消了交易。
我需要从客户端(手持式/CF)应用程序向我的 Web API 应用程序发送几个 args 和一个文件。
我可能已经从这里找到了接收它的代码 [ http://www.asp.net/web-api/overview/working-with-http/sending-html-form-data,-part-2]
具体来说,这里的 Wasson 控制器代码看起来很可能会工作:
public async Task<HttpResponseMessage> PostFile()
{
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
try
{
StringBuilder sb = new StringBuilder(); // Holds the response body
// Read the form data and return an async task.
await Request.Content.ReadAsMultipartAsync(provider);
// This illustrates how to get the form data.
foreach (var key in provider.FormData.AllKeys)
{
foreach (var val in provider.FormData.GetValues(key))
{
sb.Append(string.Format("{0}: {1}\n", key, val));
}
}
// This illustrates how to get the file names for uploaded files.
foreach (var file in provider.FileData)
{
FileInfo fileInfo = new FileInfo(file.LocalFileName);
sb.Append(string.Format("Uploaded file: {0} ({1} bytes)\n", fileInfo.Name, fileInfo.Length));
}
return new HttpResponseMessage()
{
Content = new StringContent(sb.ToString())
};
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
...但是现在我需要知道如何发送它;来自客户端的其他调用形式为:
http://<IPAddress>:<portNum>/api/<ControllerName>?arg1=Bla&arg2=Blee
但是我需要发送/附加的文件如何传递?这是一个 XML 文件,但我不想将整个内容附加到 URI,因为它可能非常大,这样做会非常奇怪。
有人知道怎么做吗?
更新
根据 tvanfosson 掉在下面的碎屑,我找到了代码 here,我认为我可以适应在客户端上工作:
var message = new HttpRequestMessage();
var content = new MultipartFormDataContent();
foreach (var file in files)
{
var filestream = new FileStream(file, FileMode.Open);
var fileName = System.IO.Path.GetFileName(file);
content.Add(new StreamContent(filestream), "file", fileName);
}
message.Method = HttpMethod.Post;
message.Content = content;
message.RequestUri = new Uri("http://localhost:3128/api/uploading/");
var client = new HttpClient();
client.SendAsync(message).ContinueWith(task =>
{
if (task.Result.IsSuccessStatusCode)
{
//do something with response
}
});
...但这取决于Compact Framework supports MultipartFormDataContent
更新 2
根据How can i determine which .Net features the compact framework has?,事实并非如此
更新 3
使用 C# 扩展的 Bing 搜索代码,我捣碎了“h”,选择了“我该怎么做”,输入“通过 http 发送文件”并得到这个:
WebRequest request = WebRequest.Create("http://www.contoso.com/PostAccepter.aspx ");
request.Method = "POST";
string postData = "This is a test that posts this string to a Web server.";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse response = request.GetResponse();
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
Console.WriteLine(responseFromServer);
reader.Close();
dataStream.Close();
response.Close();
除了文件之外我还需要添加几个字符串参数(我假设我可以通过 postData 字节数组添加),我可以通过添加更多对 dataStream.Write() 的调用来做到这一点吗? IOW,这是否明智(第一行和第三行不同):
WebRequest request = WebRequest.Create("http://MachineName:NNNN/api/Bla?str1=Blee&str2=Bloo");
request.Method = "POST";
string postData = //open the HTML file and assign its contents to this, or make it File postData instead of string postData?
// the rest is the same
?
更新 4
进度:这个,就是这样,正在工作:
服务器代码:
public string PostArgsAndFile([FromBody] string value, string serialNum, string siteNum)
{
string s = string.Format("{0}-{1}-{2}", value, serialNum, siteNum);
return s;
}
客户端代码(来自 this post 中的 Darin Dimitrov):
private void ProcessRESTPostFileData(string uri)
{
using (var client = new WebClient())
{
client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
var data = "=Short test...";
var result = client.UploadString(uri, "POST", data);
//try this: var result = client.UploadFile(uri, "bla.txt");
//var result = client.UploadData()
MessageBox.Show(result);
}
}
现在我需要让它在 [FromBody] arg 中发送一个文件而不是一个字符串。
【问题讨论】:
标签: c# http asp.net-web-api compact-framework multipartform-data