Blazor WebAssembly PWA-IFormFile FromForm始终为null

时间:2020-06-30 19:52:34

标签: c# asp.net-core blazor azure-cognitive-services blazor-client-side

我已经建立了一个Blazor WebAssembly ASP.Net Core hosted PWA项目,并且正在其中使用Azure Cognitive Services。因此,在我的一个客户端视图中,我有一个表单,用户可以在其中上传图像,这将被称为Azure。

在剃须刀视图中,我有这个:

@inject HttpClient client;
@inject IFileReaderService FileReader;
@inject NavigationManager navi;

<div class="text-center">
    <input class="btn btn-secondary " name="file" @ref="InpReference" type="file" id="file-selector" placeholder="Brows" accept="image/*" capture="camera" @onclick="InputFile">

    @if (_fileSelected != false)
    {
        <input class="btn btn-primary" type="button" role="button" id="startbutton" @onclick="Upload" value="upload" />
    }
</div>

@code {
        private async Task Upload()
        {
            // content base structure
            MultipartFormDataContent content = new MultipartFormDataContent();
            content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data");
    
            
            foreach (/*IFileReference*/var fileReference in fileReferences)
            {
                Console.WriteLine("test1");
                // getting the file size
                IFileInfo fileinfo = await fileReference.ReadFileInfoAsync();
                Stream fileStream;
                var fileReferencesArray = fileReferences.ToArray();
                using (var fs = await fileReference.CreateMemoryStreamAsync((int)fileinfo.Size))
                {
                    Console.WriteLine("test2");
                    fileStream=new MemoryStream(fs.ToArray());
                }
                Console.WriteLine("test4" + fileinfo.Size);
                StreamContent sc = new StreamContent(fileStream, (int)fileStream.Length);
                content.Add(sc, "file", fileinfo.Name);
                Console.WriteLine("test5");
            }
            Console.WriteLine("test6");
            var response = await client.PostJsonAsync<List<Prediction>>("api/Azure/Prediction", content);
            Console.WriteLine(response.Count + " : " + response.GetType().ToString());
            foreach (var prediction in  response)
            {
                Console.WriteLine(prediction.Id + ":" + prediction.Name + "," + prediction.Probability.ToString());
            }
            navi.NavigateTo("detailView/");
    
    
        }
}

我的WebApi控制器用于处理:

    ...
        [HttpPost]
        public List<Prediction> getPrediction([FromForm]IFormFile file)
        {
            if (file == null)
            {
                return new List<Prediction>();
            }
            List<Prediction> predicitions = azure_Client.GetPrediction(file.OpenReadStream());
            return predicitions;
        }
    ...

问题是控制器中的[FromForm]IFormFile file始终为null。仅在PWA项目中为空。我已经设置了没有PWA的同一项目,它有效,它不是null,并且正在从视图中获取选定的图像!那里有什么区别,为什么HttpClientBlazor WebAssembly ASP.Net Core hosted一样?

1 个答案:

答案 0 :(得分:1)

根据我的测试,如果要在Blazor WebAssembly ASP.Net Core托管的PWA中上传文件,请参考以下步骤

  1. 客户端(我使用sdk Tewr.Blazor.FileReader

    a。更新Program.cs

    builder.Services.AddFileReaderService(options => {
              options.UseWasmSharedBuffer = true;
          });
          builder.Services.AddTransient(sp =>
              new HttpClient
              {
                  BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
              });
    

    b。上传文件razor-view

@using System.IO
@using Blazor.FileReader

@inject HttpClient client;
@inject IFileReaderService fileReader
<h1>File uplaod Blzaor WebAssembly!</h1>
<div class="row">
    <div class="col-4">
        <div class="form-group">
            <input type="file" name="image" @ref="inputReference" @onchange="async() =>await OpenFile()" />
            <ul>
                <li>File Name: @fileName</li>
                <li>Size: @size</li>
                <li>Type: @type</li>
            </ul>

        </div>
        <button class="btn btn-block btn-success" @onclick="async() =>await UploadFile()"> Upload File</button>
        @if (!string.IsNullOrWhiteSpace(message))
        {
            <div class="alert alert-success">
                File has been uplaoded
            </div>

        }
    </div>   
</div>


@code{
    ElementReference inputReference;
    string message = string.Empty;
    string fileName = string.Empty;
    string type = string.Empty;
    string size = string.Empty;
    Stream fileStream=null;

    async Task UploadFile()
    {
        var content = new MultipartFormDataContent();
        content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data");
        var sc = new StreamContent(fileStream, (int)fileStream.Length);
        content.Add(sc, "image", fileName);


        var response = await client.PostAsync("/upload", content);
        if (response.IsSuccessStatusCode) {
            message = "OK";
        }

    }

    async Task OpenFile()
    {
        var file = (await fileReader.CreateReference(inputReference).EnumerateFilesAsync()).FirstOrDefault();

        if (file == null) {
            return;
        }

        var fileInfo=await file.ReadFileInfoAsync();
        fileName = fileInfo.Name;
        type = fileInfo.Type;
        size = $"{fileInfo.Size} Bytes";

        using (var ms = await file.CreateMemoryStreamAsync((int)fileInfo.Size)) {
            fileStream = new MemoryStream(ms.ToArray());
        }
    }



}
  1. 服务器

API COntroller

 [HttpPost]
        public async Task<IActionResult> Post([FromForm(Name ="image")]IFormFile file) {

            if (file == null || file.Length == 0) {
                return BadRequest("do not receive file");
            }

            var fileName = file.FileName;
            var extension = Path.GetExtension(fileName);
            var newFileName = $"{Guid.NewGuid()}{extension}";
            var filePath = Path.Combine(_env.ContentRootPath, "Images", newFileName);
            if (!Directory.Exists(Path.Combine(_env.ContentRootPath, "Images"))) {
                Directory.CreateDirectory(Path.Combine(_env.ContentRootPath, "Images"));
            
            }
            using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write)) {
                await file.CopyToAsync(stream);
            }
            
            return Ok(filePath);
        
        }
  1. 结果

enter image description here enter image description here