如何从JObject获取Iformfile值?

时间:2018-04-19 03:41:34

标签: asp.net-core-2.0 asp.net-core-webapi jobjectformatter

我使用最新的.net核心,我有mvc应用程序和web Api应用程序,所以mvc应用程序接受请求,所有数据库操作都是通过web api应用程序完成的,我大部分时间都遇到了困难用于上传图像的IFormFile以某种方式我设法获取图像数据并绑定到ViewModel然而当我将ViewModel作为PostAsJsonAsync传递给web api控制器时,其参数是viewmodel它没有工作所以我改为JObject,现在我的问题是如何从IFbject中提取IFormFile属性作为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">&times;</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 个答案:

答案 0 :(得分:0)

既然你提到了财产,那就说有一个有财产的类:

public class MyData
{
    public IFormFile File { get; set; }
}

我现在可以在控制器中使用它:

public IActionResult UploadFile([FromForm]MyData data)
{

}

当您使用正确的密钥data.File传递表单数据时,您的File现在将包含该文件。

答案 1 :(得分:0)

首先,不要绑定到JObject。创建一个真实的视图模型并绑定到该模型。

public class ItemViewModel
{
    public int Number { get; set; }
    public byte[] File { get; set; }
}

然后:

public void AddDetails([FromBody]ItemViewModel data)

其次,要通过JSON发布文件,您必须将其作为base64编码的byte[](将使其成为字符串)发送。如果通过您的视图模型将模板绑定到模型绑定器,模型绑定器将自动将其解码为真正的byte[]

如果您不想在客户端对其进行base64编码,则必须将其发布为multipart/form-data,在这种情况下,您需要绑定已发布的内容档案到IFormFile。这意味着您将上面的视图模型类中的File属性更改为:

public IFormFile File { get; get; }