使用 InputFile组件将浏览器文件数据读入 .NET 代码,在用户选择文件后发生 OnChange (change) 事件时, InputFile 组件执行 LoadFiles 方法参数 InputFileChangeEventArgs 提供对所选文件列表和每个文件的详细信息的访问
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<InputFile OnChange="@LoadFiles" multiple/>
@code {
private List<IBrowserFile> BrowserFiles = new();
private int maxAllowFiles=3;
private long maxFileSize = 1024 * 1024 * 5;
private void LoadFiles(InputFileChangeEventArgs e)
{
try
{
BrowserFiles.AddRange(e.GetMultipleFiles(maxAllowFiles));
}
catch (InvalidOperationException ex)
{
_logger.LogError($"only allow {maxAllowFiles} files upload; message{ex.Message}");
}
Console.WriteLine($"{BrowserFiles.Count} files upload");
BrowserFiles.Clear();
}
}
调用 IBrowserFile.OpenReadStream,并从返回的流中读取文件内容。OpenReadStream 强制采用其 Stream 的最大大小(以字节为单位)。 读取一个或多个大于 512,000 字节 (500 KB) 的文件会引发异常。 此限制可防止开发人员意外地将大型文件读入到内存中。 如果需要,可以使用 OpenReadStream 上的 maxAllowedSize 参数指定更大的大小,如果超过这个大小就报出错误
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
private void LoadFiles(InputFileChangeEventArgs e)
{
try
{
BrowserFiles.AddRange(e.GetMultipleFiles(maxAllowFiles));
}
catch (InvalidOperationException ex)
{
_logger.LogError($"only allow {maxAllowFiles} files upload; message{ex.Message}");
}
if (BrowserFiles.Count > 0)
{
foreach (var file in BrowserFiles)
{
try
{
var fileContent = file.OpenReadStream(maxAllowedSize: maxFileSize);
}
catch (Exception ex)
{
_logger.LogError($"{file.Name} not uploaded (Err: 6): {ex.Message}");
}
}
}
Console.WriteLine($"{BrowserFiles.Count} files upload");
上传文件到AzureBlob
Azure Storage Blobs 暂不支持wasm所以无法从blazor wasm应用中直接上传文件到azure blob上得通过相应api上传文件。通过命令 dotnet new webapi —name FileUpload 创建webapi项目引用Azure blob,在Program.cs文件中注入BlobContainerClient
1
2
3
4
5
6
7
8
9
10
// Add services to the container.
builder.Services.Configure<AzureStorageOption>(builder.Configuration.GetSection("AzureStorage"));
AzureStorageOption AzureStorageOption = new();
builder.Configuration.GetSection("AzureStorage").Bind(AzureStorageOption);
builder.Services.AddScoped(_ =>
{
var blobContainerClient = new BlobContainerClient(AzureStorageOption.StorageConnectionString, AzureStorageOption.ContainerName);
blobContainerClient.CreateIfNotExists();
return blobContainerClient;
});
新增Controller 在FileController.cs 文件中增加uploadfile接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
[ApiController]
[Route("api/[Controller]/[action]")]
public class FileController : Controller
{
private readonly BlobContainerClient blobContainerClient;
private readonly ILogger<FileController> logger;
private readonly AzureStorageOption storageOption;
public FileController(BlobContainerClient blobContainerClient,
ILogger<FileController> logger,
IOptionsMonitor<AzureStorageOption> optionsMonitor)
{
this.blobContainerClient = blobContainerClient;
this.logger = logger;
storageOption = optionsMonitor.CurrentValue;
}
[HttpPost]
[ActionName("UploadFile")]
public async Task<IActionResult> UploadFile()
{
var formCollection = await Request.ReadFormAsync();
var file = formCollection.Files.First();
if (file.Length <= 0) return BadRequest();
if (!storageOption.Format.Contains(Path.GetExtension(file.FileName).TrimStart('.'),StringComparison.OrdinalIgnoreCase))
{
return BadRequest();
}
try
{
var blobFile = blobContainerClient.GetBlobClient(file.FileName);
await blobFile.DeleteIfExistsAsync(DeleteSnapshotsOption.IncludeSnapshots);
using var fileStream = file.OpenReadStream();
await blobFile.UploadAsync(fileStream, new BlobHttpHeaders { ContentType = file.ContentType });
return Ok(blobFile.Uri.ToString());
}
catch (Exception ex)
{
logger.LogError(ex.Message);
return StatusCode(500, ex.Message);
}
}
}
在webapi Program.cs 中配置cors策略允许不同域的应用程序可以调用api
1
2
3
4
5
6
builder.Services.AddCors(policy => {
policy.AddPolicy("CorsPolicy",
opt => opt.SetIsOriginAllowed(s => true)
.AllowAnyMethod()
.AllowAnyHeader());
});
在blazor wasm应用中注入的HttpClient设置BaseAddress builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri("https://localhost:7124/api/") });
blazor wasm FileOperation.razor 组件中允许用户从客户端上传文件,在用户界面中显示由客户端提供的不可信/不安全的文件名,不受信任/不安全的文件名由Razor自动进行HTML编码,以便在用户界面中安全显示。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
@code {
private List<IBrowserFile> BrowserFiles = new();
private int maxAllowFiles=3;
private long maxFileSize = 1024 * 1024 * 5;
public string? imgUrl { get; set; }
private async Task LoadFiles(InputFileChangeEventArgs e)
{
try
{
BrowserFiles.AddRange(e.GetMultipleFiles(maxAllowFiles));
}
catch (InvalidOperationException ex)
{
_logger.LogError($"only allow {maxAllowFiles} files upload; message{ex.Message}");
}
if (BrowserFiles.Count > 0)
{
var file = BrowserFiles.First();
using var fileContent = file.OpenReadStream(maxFileSize);
MultipartFormDataContent httpContent = new();
httpContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data");
httpContent.Add(new StreamContent(fileContent), "file", file.Name);
var response = await HttpClient.PostAsync("File/UploadFile", httpContent);
imgUrl = await response.Content.ReadAsStringAsync();
//foreach (var file in BrowserFiles)
//{
// try
// {
// var fileContent = file.OpenReadStream(maxAllowedSize: maxFileSize);
// }
// catch (Exception ex)
// {
// _logger.LogError($"{file.Name} not uploaded (Err: 6): {ex.Message}");
// }
//}
}
Console.WriteLine($"{BrowserFiles.Count} files upload");
BrowserFiles.Clear();
await Task.CompletedTahe
文件显示
选择文件上传到azure blob上返回文件的url路径,在img标签中显示图片内容
1
2
3
4
5
6
@if(imgUrl!=null)
{
<div>
<img src="@imgUrl" class="image-preview" />
</div>
}