-2

我正在使用最新的 .net 核心,我有 mvc 应用程序和 web Api 应用程序,所以 mvc 应用程序需要请求,所有数据库操作都是由 web api 应用程序完成的,我大部分时间都被卡在与 IFormFile 相关的上传图像所以不知何故我设法获取图像数据并绑定到 ViewModel 但是当我将 ViewModel 作为 PostAsJsonAsync 传递给参数为 viewmodel 的 web api 控制器时它不起作用所以我更改为 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">&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());

}
4

2 回答 2

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[]如果这是您通过视图模型将其绑定到的内容,modelbinder 将自动将其 base64 解码回 true 。

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

public IFormFile File { get; get; }
于 2018-04-19T13:52:46.110 回答
0

既然您提到了属性,假设有一个具有属性的类:

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

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

public IActionResult UploadFile([FromForm]MyData data)
{

}

data.File现在将包含文件,只要您使用正确的键传递表单数据File

于 2018-04-19T08:47:41.547 回答