【问题标题】:How to get Iformfile value from JObject?如何从 JObject 获取 Iformfile 值?
【发布时间】:2018-09-29 10:35:57
【问题描述】:

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

}

【问题讨论】:

  • 这通常直接来自控制器。文件来自哪里?

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


【解决方案1】:

既然你提到了属性,假设有一个类有一个属性:

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

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

public IActionResult UploadFile([FromForm]MyData data)
{

}

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

【讨论】:

  • 嗨@Neville Nazerane,那是我没有被卡住的地方,真正的问题是调用web Api,它需要JObject,我已按问题编辑,请检查。
  • 根据我过去的所有尝试,对于文件上传,您必须使用 [FromForm] 和正确的内容类型。默认情况下,jquery 使用文本作为内容类型
  • 嗨@Neville Nazerane,那么你推荐什么解决方案......我看不出有什么办法摆脱它......如果你有任何代码示例,请告诉我。
  • 嗨@Neville Nazerane,我会尝试你的解决方案并让你知道
【解决方案2】:

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

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

然后:

public void AddDetails([FromBody]ItemViewModel data)

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

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

public IFormFile File { get; get; }

【讨论】:

  • 嗨@Chris Pratt,那是我没有被卡住的地方,真正的问题是调用web Api,它需要JObject,我已按问题编辑,请检查。
  • 问题首先在于绑定到 JObject。让模型绑定器按应有的方式处理绑定和强制转换。您还可以获得内置验证,而 JObject 根本没有。一旦你绑定了一个真正的类,你只需要一个 byte[] 或 IFormFile 的属性,这取决于你发送的内容(即 JSON 或表单数据)。然后一切正常。
  • 嗨@chris patt,我没听懂你,我正在使用Jobject,因为除了web api中的模型类之外,没有办法绑定,而且主要问题是使用Iformfile,如果你试试我的代码你会意识到问题,如果你找到任何解决方案,请告诉我。
  • 没有办法绑定是什么意思?如果你不能使用真实的模型,那你就做错了。简单明了,您无法使用 JObject 实现您想要做的事情。时期。故事结局。使用您认为行不通的真实模型更新您的问题,我们可能会为您提供帮助,而不是坚持走这条错误的道路。
  • 嗨@Chris Pratt,我想我已经多次提到 IFormfile 我们无法以正常方式实现这个原因 JObject ..现在只是我对你的正常问题我们如何从 JObject 中提取 Iformfile 内容并将其分配给 Iformfile.. 如果您知道答案,请帮助或离开它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多