【问题标题】:How can I simultaneously pass args and upload a file to a Web API Controller Method?如何同时传递参数并将文件上传到 Web API 控制器方法?
【发布时间】: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


    【解决方案1】:

    您应该考虑将 multipart/form-data 与自定义媒体类型格式化程序一起使用,该格式化程序将提取字符串属性和上传的 XML 文件。

    http://lonetechie.com/2012/09/23/web-api-generic-mediatypeformatter-for-file-upload/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-15
      • 1970-01-01
      • 2015-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多