Как получить значение Iformfile из JObject?
Я использую последнее ядро .net, у меня есть приложение mvc и веб-приложение Api, поэтому приложение mvc принимает запрос, и все операции над базой данных выполняются приложением веб-API. Я застрял большую часть времени в связи с IFormFile для загрузки изображения, так или иначе. Мне удалось получить данные изображения и привязать его к ViewModel, однако, когда я передаю ViewModel как PostAsJsonAsync в контроллер веб-API, у которого параметр viewmodel, он не работает, поэтому я перешел на JObject, и теперь моя проблема заключается в том, как извлечь свойство IFormFile. из JObject как IFormFile, я сталкиваюсь с ошибкой InvalidCastException. Вот мой код
//HTML File
<div class="control-label col-md-2">
@Html.Label("Image")
</div>
<div class="col-md-3 imgdrop">
<input type="file" id="file" name="file"class="form-control-file" />
<div class="img-wrap ">
<span class="close">×</span>
<img src="..." alt="..." id="imgInp" class="img-fluid" />
</div>
</div>
$("#SaveDetailsId").on("click", function () {
var formdata = new FormData();
var table = $("#ItemListTable").DataTable();
$.each(tableData, function (index, item) {
name = 'ItemList[' + index + '].SkuList'; // construct the name
value = item[0];
});
formdata.append("ImageFile", jQuery("#file").get(0).files[0]);
$.ajax({
//headers: {
// 'Accept': 'application/json',
// 'Content-Type': 'application/json'
//},
url: "/Test/Test",
type: "POST",
data: formdata,
contentType: false,
processData: false,
success: function (response) {
...
});
});
//ViewModel
public class Test
{
public IFormFile ImageFile {get;set;}
.
.
.
}
//MVC Controller
[HttpPost]
public async Task<IActionResult> BuyerCreative([FromForm]Test _viewModel)
{
_viewModel.Ad = _viewModel.Ad;
using (var client = new HttpClient())
{
//Passing service base url
client.BaseAddress = new Uri(Baseurl);
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage Res = await client.PostAsJsonAsync("api/Test/Test", _viewModel);
if (Res.IsSuccessStatusCode)
{
}
//returning the employee list to view
return View(_viewModel);
}
}
//Let me know if there is a way to bind ViewModel instead of JObject
//WEbApi
[Route("api/Test/Test/")]
[HttpPost]
public IActionResult Test([FromBody] JObject data)
{
try
{
_Repository.AddDetails(data);
return Ok();
}
catch (Exception pException)
{
return BadRequest(pException.Message);
}
}
//And Lastly my repository
public void AddDetails(JObject data)
{
DBContext.Items _items = new DBContext.Items();
_items.Number = Convert.ToInt32(((JValue)data.GetValue("Number")).Value);
// I 'm stuck over here, how to get the IFormFile, I tried various options
IFormFile file = (IFormFile)((JValue)data.GetValue("ImageFile"));
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(_connectionString);
// Create a blob client for interacting with the blob service.
blobClient = storageAccount.CreateCloudBlobClient();
blobContainer = blobClient.GetContainerReference(blobContainerName);
blobContainer.CreateIfNotExistsAsync();
blobContainer.SetPermissionsAsync(new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Blob });
var fileContent = reader.ReadToEnd();
var parsedContentDisposition = ContentDispositionHeaderValue.Parse(file.ContentDisposition);
fileName = parsedContentDisposition.FileName;
CloudBlockBlob blob = blobContainer.GetBlockBlobReference(fileName);
blob.UploadFromStreamAsync(file.OpenReadStream());
}
2 ответа
Во-первых, не связывайтесь с JObject
, Создайте реальную модель представления и привязайтесь к ней.
public class ItemViewModel
{
public int Number { get; set; }
public byte[] File { get; set; }
}
Затем:
public void AddDetails([FromBody]ItemViewModel data)
Во-вторых, чтобы опубликовать файл через JSON, вы должны отправить его в формате base64. byte[]
(что сделает его строкой). Связыватель модели автоматически base64-декодирует его обратно в истинное byte[]
, если это то, к чему вы привязываете это через вашу модель представления.
Если вы не хотите, чтобы base64-кодировал его на стороне клиента, вы должны опубликовать его как multipart/form-data
, в этом случае вам нужно будет привязать опубликованный файл к IFormFile
, Что означает, что вы измените File
свойство в классе модели представления выше, чтобы:
public IFormFile File { get; get; }
Поскольку вы упомянули свойство, скажем, есть класс со свойством:
public class MyData
{
public IFormFile File { get; set; }
}
Теперь я могу использовать это в контроллере:
public IActionResult UploadFile([FromForm]MyData data)
{
}
Ваш data.File
теперь будет содержать файл, если вы передадите данные формы с правильным ключом File
,