ASP.NET Core使用HTTPClient使用ViewModel发布表单数据IFormFile

编程入门 行业动态 更新时间:2024-10-28 00:22:51
本文介绍了ASP.NET Core使用HTTPClient使用ViewModel发布表单数据IFormFile的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在构建WebAPI&WebApp,它们都使用ASP.NET Core 2.1

我的Web应用程序正尝试使用包含IFormFile和其他属性的ViewModel将发布请求发送到Web API.我知道我必须使用 MultipartFormDataContent 来发布IFormFile,但是我不知道如何使用ViewModel来实现它,因为我的ViewModel具有其他模型的 List .

我已经尝试过搜索一些解决方案,但是我只找到了简单的ViewModel而没有类似List的解决方案:

I'm building WebAPI & WebApp, both of them using ASP.NET Core 2.1

My Web App is trying to send post request to the Web API using ViewModel that contains IFormFile and other properties. I know I have to use MultipartFormDataContent to post IFormFile, but I don't know how to implement it with my ViewModel because my ViewModel has List of other model.

I already try to google some solutions, but I only found solutions with simple ViewModel without List like these :

stackoverflow/a/41511354/7906006

stackoverflow/a/55424886/7906006.


Is there any solution like

var multiContent = new MultipartFormDataContent(); var viewModelHttpContent= new StreamContent(viewModel); MultiContent.Add(viewModelHttpContent, "viewModel"); var response = await client.PostAsJsonAsync("/some/url", multiContent);

so i don't have to add my property to MultipartFormDataContent one by one and post it as json.


Here's my Web App 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 }

Here's my Web App controller

[HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create(CreateDataViewModel viewModel) { //How to implement MultipartFormDataContent with my ViewModel in here ? //My code below returns Could not create an instance of type Microsoft.AspNetCore.Http.IHeaderDictionary. Type is an interface or abstract class and cannot be instantiated. Path 'Attachment.Headers.Content-Disposition', line 1, position 723. //It works fine if I don't upload a file HttpResponseMessage res = await _client.PostAsJsonAsync<CreateDataViewModel>("api/data/create", viewModel); var result = res.Content.ReadAsStringAsync().Result; if (res.IsSuccessStatusCode) { TempData["FlashMessageSuccess"] = "Data have been submitted"; return RedirectToAction("Index", "Home"); ; } //Code for error checking }

Here's my Web API controller that catches the post response using CreateDataViewModel as parameter.

[HttpPost] [Route("[action]")] public async Task<IActionResult> Create(CreateDataViewModel viewModel) { //Code to validate then save the data }

解决方案

don't know how to implement it with my ViewModel because my ViewModel has List of other model

You can refer to following code snippet and implement a custom model binder to achieve your requirement.

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);

Implement a custom model binder to convert incoming request data

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; }

Apply it on API action method

public async Task<IActionResult> Create([ModelBinder(BinderType = typeof(CustomModelBinder))]CreateDataViewModel viewModel)

Test Result

更多推荐

ASP.NET Core使用HTTPClient使用ViewModel发布表单数据IFormFile

本文发布于:2023-11-14 16:28:43,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1587955.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:表单   数据   Core   NET   ASP

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!