Asp.net mvc 使用HTTPClient的ASP.NET核心Post表单数据文件和ViewModel
我正在构建WebAPI和WebApp,它们都使用ASP.NET Core 2.1 我的Web应用程序正在尝试使用包含文件和其他属性的ViewModel向Web API发送post请求。我知道我必须使用Asp.net mvc 使用HTTPClient的ASP.NET核心Post表单数据文件和ViewModel,asp.net-mvc,rest,api,asp.net-core,asp.net-web-api,Asp.net Mvc,Rest,Api,Asp.net Core,Asp.net Web Api,我正在构建WebAPI和WebApp,它们都使用ASP.NET Core 2.1 我的Web应用程序正在尝试使用包含文件和其他属性的ViewModel向Web API发送post请求。我知道我必须使用MultipartFormDataContent发布IFormFile,但我不知道如何用我的ViewModel实现它,因为我的ViewModel有其他模型的列表 我已经尝试用谷歌搜索了一些解决方案,但我只找到了带有简单ViewModel的解决方案,没有如下列表: 有没有类似的解决方案 var
MultipartFormDataContent
发布IFormFile,但我不知道如何用我的ViewModel实现它,因为我的ViewModel有其他模型的列表
我已经尝试用谷歌搜索了一些解决方案,但我只找到了带有简单ViewModel的解决方案,没有如下列表:
有没有类似的解决方案
var multiContent = new MultipartFormDataContent();
var viewModelHttpContent= new StreamContent(viewModel);
MultiContent.Add(viewModelHttpContent, "viewModel");
var response = await client.PostAsJsonAsync("/some/url", multiContent);
因此,我不必将我的属性逐个添加到MultipartFormDataContent
并将其作为json发布
这是我的Web应用程序ViewModel
public class CreateDataViewModel
{
public string PrimaryKeyNumber{ get; set; }
public List<Currency> ListOfCurrency { get; set; }
public IList<DataDetail> dataDetails { get; set; }
[DataType(DataType.Upload)]
public IFormFile Attachment { get; set; }
//And other properties like Boolean, Datetime?, string
}
我不知道如何用我的ViewModel实现它,因为我的ViewModel有其他模型的列表
您可以参考以下代码片段并实现自定义模型绑定器以实现您的需求
var multipartContent = new MultipartFormDataContent();
multipartContent.Add(new StringContent(viewModel.PrimaryKeyNumber), "PrimaryKeyNumber");
multipartContent.Add(new StringContent(JsonConvert.SerializeObject(viewModel.ListOfCurrency)), "ListOfCurrency");
multipartContent.Add(new StringContent(JsonConvert.SerializeObject(viewModel.dataDetails)), "dataDetails");
multipartContent.Add(new StreamContent(viewModel.Attachment.OpenReadStream()), "Attachment", viewModel.Attachment.FileName);
var response = await client.PostAsync("url_here", multipartContent);
实现自定义模型绑定器以转换传入的请求数据
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
// code logic here
// ...
// ...
// fetch the value of the argument by name
// and populate corresponding properties of your view model
var model = new CreateDataViewModel()
{
PrimaryKeyNumber = bindingContext.ValueProvider.GetValue("PrimaryKeyNumber").FirstOrDefault(),
ListOfCurrency = JsonConvert.DeserializeObject<List<Currency>>(bindingContext.ValueProvider.GetValue("ListOfCurrency").FirstOrDefault()),
dataDetails = JsonConvert.DeserializeObject<List<DataDetail>>(bindingContext.ValueProvider.GetValue("dataDetails").FirstOrDefault()),
Attachment = bindingContext.ActionContext.HttpContext.Request.Form.Files.FirstOrDefault()
};
bindingContext.Result = ModelBindingResult.Success(model);
return Task.CompletedTask;
}
公共任务BindModelAsync(ModelBindingContext bindingContext)
{
if(bindingContext==null)
{
抛出新ArgumentNullException(nameof(bindingContext));
}
//这里的代码逻辑
// ...
// ...
//按名称获取参数的值
//并填充视图模型的相应属性
var model=new CreateDataViewModel()
{
PrimaryKeyNumber=bindingContext.ValueProvider.GetValue(“PrimaryKeyNumber”).FirstOrDefault(),
ListOfCurrency=JsonConvert.DeserializeObject(bindingContext.ValueProvider.GetValue(“ListOfCurrency”).FirstOrDefault()),
dataDetails=JsonConvert.DeserializeObject(bindingContext.ValueProvider.GetValue(“dataDetails”).FirstOrDefault()),
附件=bindingContext.ActionContext.HttpContext.Request.Form.Files.FirstOrDefault()
};
bindingContext.Result=ModelBindingResult.Success(model);
返回Task.CompletedTask;
}
将其应用于API操作方法
public async Task<IActionResult> Create([ModelBinder(BinderType = typeof(CustomModelBinder))]CreateDataViewModel viewModel)
公共异步任务创建([ModelBinder(BinderType=typeof(CustomModelBinder))]CreateDataViewModel视图模型)
测试结果
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
// code logic here
// ...
// ...
// fetch the value of the argument by name
// and populate corresponding properties of your view model
var model = new CreateDataViewModel()
{
PrimaryKeyNumber = bindingContext.ValueProvider.GetValue("PrimaryKeyNumber").FirstOrDefault(),
ListOfCurrency = JsonConvert.DeserializeObject<List<Currency>>(bindingContext.ValueProvider.GetValue("ListOfCurrency").FirstOrDefault()),
dataDetails = JsonConvert.DeserializeObject<List<DataDetail>>(bindingContext.ValueProvider.GetValue("dataDetails").FirstOrDefault()),
Attachment = bindingContext.ActionContext.HttpContext.Request.Form.Files.FirstOrDefault()
};
bindingContext.Result = ModelBindingResult.Success(model);
return Task.CompletedTask;
}
public async Task<IActionResult> Create([ModelBinder(BinderType = typeof(CustomModelBinder))]CreateDataViewModel viewModel)