我有一个WebService,它正在使用POST方法工作并接收文件,但是在其中我还需要同时接收数据。
ASP.NET WebApi代码:
public Task<HttpResponseMessage> Post()
{
HttpRequestMessage request = this.Request;
if (!request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = System.Web.HttpContext.Current.Server.MapPath("~/App_Data/uploads");
var provider = new MultipartFormDataStreamProvider(root);
var task = request.Content.ReadAsMultipartAsync(provider).
ContinueWith<HttpResponseMessage>(o =>
{
string file1 = provider.FileData.First().LocalFileName;
return new HttpResponseMessage()
{
Content = new StringContent("File uploaded.")
};
}
);
return task;
}
为Android开发的客户端正在发送文件和数据,如下所示(文件的发送已经过测试并且可以正常工作,数据的发送仍然没有经过测试,因为我需要它能够在服务器端):
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addPart(
Headers.of("Content-Disposition", "form-data; name=\"title\""),
RequestBody.create(null, "Sample Text Content"))
.addPart(
Headers.of("Content-Disposition", "form-data; name=\"file\"; filename=\"" + fileName + ".png\""),
RequestBody.create(MEDIA_TYPE_PNG, bitmapdata))
.addFormDataPart("fullpath", "test")
.build();
final com.squareup.okhttp.Request request = new com.squareup.okhttp.Request.Builder()
.url(url)
.post(requestBody)
.build();
如何更改服务器以读取文件和数据?
有人可以帮忙吗? 预先感谢。
答案 0 :(得分:1)
在这种情况下,客户端android在体内发送了其他值,例如media_type_png。我必须做类似的事情,但是客户端是有角度的,而不是移动应用程序,经过一番搜索之后,我从下面的stackoverflow中找到了代码。产生了下面的代码。
首先接收传入的消息,并检查您是否可以处理它,即[IsMimeMultipartContent][1]()
[HttpPost]
public async Task<HttpResponseMessage> Upload()
{
// Here we just check if we can support this
if (!Request.Content.IsMimeMultipartContent())
{
this.Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);
}
// This is where we unpack the values
var provider = new MultipartFormDataMemoryStreamProvider();
var result = await Request.Content.ReadAsMultipartAsync(provider);
// From the form data we can extract any additional information Here the DTO is any object you want to define
AttachmentInformationDto attachmentInformation = (AttachmentInformationDto)GetFormData(result);
// For each file uploaded
foreach (KeyValuePair<string, Stream> file in provider.FileStreams)
{
string fileName = file.Key;
// Read the data from the file
byte[] data = ReadFully(file.Value);
// Save the file or do something with it
}
}
我用它来解压缩数据:
// Extracts Request FormatData as a strongly typed model
private object GetFormData(MultipartFormDataMemoryStreamProvider result)
{
if (result.FormData.HasKeys())
{
// Here you can read the keys sent in ie
result.FormData["your key"]
AttachmentInformationDto data = AttachmentInformationDto();
data.ContentType = Uri.UnescapeDataString(result.FormData["ContentType"]); // Additional Keys
data.Description = Uri.UnescapeDataString(result.FormData["Description"]); // Another example
data.Name = Uri.UnescapeDataString(result.FormData["Name"]); // Another example
if (result.FormData["attType"] != null)
{
data.AttachmentType = Uri.UnescapeDataString(result.FormData["attType"]);
}
return data;
}
return null;
}
MultipartFormDataMemoryStreamProvider的定义如下:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web;
namespace YOURNAMESPACE
{
public class MultipartFormDataMemoryStreamProvider : MultipartMemoryStreamProvider
{
private readonly Collection<bool> _isFormData = new Collection<bool>();
private readonly NameValueCollection _formData = new NameValueCollection(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary<string, Stream> _fileStreams = new Dictionary<string, Stream>();
public NameValueCollection FormData
{
get { return _formData; }
}
public Dictionary<string, Stream> FileStreams
{
get { return _fileStreams; }
}
public override Stream GetStream(HttpContent parent, HttpContentHeaders headers)
{
if (parent == null)
{
throw new ArgumentNullException("parent");
}
if (headers == null)
{
throw new ArgumentNullException("headers");
}
var contentDisposition = headers.ContentDisposition;
if (contentDisposition == null)
{
throw new InvalidOperationException("Did not find required 'Content-Disposition' header field in MIME multipart body part.");
}
_isFormData.Add(String.IsNullOrEmpty(contentDisposition.FileName));
return base.GetStream(parent, headers);
}
public override async Task ExecutePostProcessingAsync()
{
for (var index = 0; index < Contents.Count; index++)
{
HttpContent formContent = Contents[index];
if (_isFormData[index])
{
// Field
string formFieldName = UnquoteToken(formContent.Headers.ContentDisposition.Name) ?? string.Empty;
string formFieldValue = await formContent.ReadAsStringAsync();
FormData.Add(formFieldName, formFieldValue);
}
else
{
// File
string fileName = UnquoteToken(formContent.Headers.ContentDisposition.FileName);
Stream stream = await formContent.ReadAsStreamAsync();
FileStreams.Add(fileName, stream);
}
}
}
private static string UnquoteToken(string token)
{
if (string.IsNullOrWhiteSpace(token))
{
return token;
}
if (token.StartsWith("\"", StringComparison.Ordinal) && token.EndsWith("\"", StringComparison.Ordinal) && token.Length > 1)
{
return token.Substring(1, token.Length - 2);
}
return token;
}
}
}