从HttpClient向webapi提交文件和Json数据
我想将文件和json数据从HttpClient发送到web api服务器。从HttpClient向webapi提交文件和Json数据,json,file-upload,asp.net-web-api,Json,File Upload,Asp.net Web Api,我想将文件和json数据从HttpClient发送到web api服务器。 我似乎无法通过负载访问服务器中的json,只能作为json变量 public class RegulationFilesController : BaseApiController { public void PostFile(RegulationFileDto dto) { //the dto is null here } }
我似乎无法通过负载访问服务器中的json,只能作为json变量
public class RegulationFilesController : BaseApiController
{
public void PostFile(RegulationFileDto dto)
{
//the dto is null here
}
}
以下是客户:
using (var client = new HttpClient())
{
using (var content = new MultipartFormDataContent())
{
client.BaseAddress = new Uri(ConfigurationManager.AppSettings["ApiHost"]);
content.Add(new StreamContent(File.OpenRead(@"C:\\Chair.png")), "Chair", "Chair.png");
var parameters = new RegulationFileDto
{
ExternalAccountId = "1234",
};
JavaScriptSerializer serializer = new JavaScriptSerializer();
content.Add(new StringContent(serializer.Serialize(parameters), Encoding.UTF8, "application/json"));
var resTask = client.PostAsync("api/RegulationFiles", content); //?ApiKey=24Option_key
resTask.Wait();
resTask.ContinueWith(async responseTask =>
{
var res = await responseTask.Result.Content.ReadAsStringAsync();
}
);
}
}
此示例将起作用:
但仅通过表单数据,而不是有效负载
您能否建议如何在同一请求下访问该文件以及提交的json和该文件
谢谢我尝试了许多不同的方法来提交文件数据和元数据,这是我发现的最好的方法: 不要使用MultipartFormDataContent,只对文件数据使用StreamContent。通过这种方式,您可以对文件上传进行流式处理,这样就不会占用服务器上太多的RAM。MultipartFormDataContent要求您将整个请求加载到内存中,然后将文件保存到某个本地存储器中。通过流,您还可以将流复制到其他位置,例如Azure存储容器 这解决了二进制数据的问题,现在又解决了元数据的问题。为此,请使用自定义头并将JSON序列化为该头。控制器可以读取自定义头并将其反序列化为元数据dto。标题有大小限制,请参阅(8-16KB),这是一个很大的数据量。如果您需要更多的空间,您可以执行两个单独的请求,一个用于发布最低需求,然后一个补丁用于更新任何需要的属性,这些属性超过了标头的容量 示例代码:
public class RegulationFilesController : BaseApiController
{
public async Task<IHttpActionResult> Post()
{
var isMultipart = this.Request.Content.IsMimeMultipartContent();
if (isMultipart)
{
return this.BadRequest("Only binary uploads are accepted.");
}
var headerDto = this.GetJsonDataHeader<RegulationFileDto>();
if(headerDto == null)
{
return this.BadRequest("Missing X-JsonData header.");
}
using (var stream = await this.Request.Content.ReadAsStreamAsync())
{
if (stream == null || stream.Length == 0)
{
return this.BadRequest("Invalid binary data.");
}
//save stream to disk or copy to another stream
var model = new RegulationFile(headerDto);
//save your model to the database
var dto = new RegulationFileDto(model);
var uri = new Uri("NEW URI HERE");
return this.Created(uri, dto);
}
}
private T GetJsonDataHeader<T>()
{
IEnumerable<string> headerCollection;
if (!this.Request.Headers.TryGetValues("X-JsonData", out headerCollection))
{
return default(T);
}
var headerItems = headerCollection.ToList();
if (headerItems.Count() != 1)
{
return default(T);
}
var meta = headerItems.FirstOrDefault();
return !string.IsNullOrWhiteSpace(meta) ? JsonConvert.DeserializeObject<T>(meta) : default(T);
}
}
公共类RegulationFileController:BaseApiController
{
公共异步任务Post()
{
var isMultipart=this.Request.Content.IsMimeMultipartContent();
if(isMultipart)
{
返回此.BadRequest(“仅接受二进制上传”);
}
var headerDto=this.GetJsonDataHeader();
if(headerDto==null)
{
返回此.BadRequest(“缺少X-JsonData头”);
}
使用(var stream=wait this.Request.Content.ReadAsStreamAsync())
{
if(stream==null | | stream.Length==0)
{
返回此.BadRequest(“无效的二进制数据”);
}
//将流保存到磁盘或复制到另一个流
var模型=新监管文件(headerDto);
//将模型保存到数据库中
var dto=新法规(模型);
var uri=新uri(“此处为新uri”);
返回这个.Created(uri,dto);
}
}
私有T GetJsonDataHeader()
{
i可数头收集;
if(!this.Request.Headers.TryGetValues(“X-JsonData”,out headerCollection))
{
返回默认值(T);
}
var headerItems=headerCollection.ToList();
if(headerItems.Count()!=1)
{
返回默认值(T);
}
var meta=headerItems.FirstOrDefault();
return!string.IsNullOrWhiteSpace(meta)?JsonConvert.DeserializeObject(meta):默认值(T);
}
}