如何在ASP.Net Core 2.0 Razor Pages中发布IFormFile?

3
我是一名有用的助手,可以为您进行翻译。以下是需要翻译的内容:

我正在使用ASP.Net Core 2.0和Razor Pages开发一个应用程序。我一直在遵循Microsoft Docs中有关如何将文件上传到Azure Blob存储的说明,但到目前为止我还无法使其正常工作。

我有两个单独的模型类。一个用于文件上传,另一个用于Word文档。

文件上传类:

public class WordUpload
{
    public IFormFile SoundFile { get; set; }
    public IFormFile SoundFileSentence { get; set; }
}

其他类:

public class Word
{
    public int ID { get; set; }
    public string Answer { get; set; }
    public string AlternativeAnswer { get; set; }
    public string Hint { get; set; }
    public int Length { get; set; }
    public int Vowels { get; set; }
    public string Language { get; set; }
    public string Category { get; set; }
    public int Module { get; set; }
    public string Difficulty { get; set; }
    public string Sound { get; set; }
    public string SoundSentence { get; set; }
}

页面中的WordUpload.SoundFile未传递。这是问题所在,因为它总是返回null。

public class CreateModel : PageModel
{
    private readonly Data.ApplicationDbContext _context;
    private readonly IWordRepository _wordRepository;

    public CreateModel(Data.ApplicationDbContext context, IWordRepository wordRepository)
    {
        _context = context;
        _wordRepository = wordRepository;
    }

    /// <summary>
    /// OnGet triggers when the page is opened
    /// </summary>
    /// <returns></returns>
    public IActionResult OnGet()
    {
        Word = new Word
        {
            Answer = "",
            AlternativeAnswer = "",
            Hint = "Hint",
            Length = 0,
            Vowels = 0,
            Language = "DK",
            Category = "",
            Module = 0,
            Difficulty = "",
            Sound = "",
            SoundSentence = ""
        };

        return Page();
    }

    [BindProperty]
    public WordUpload WordUpload { get; set; }

    [BindProperty]
    public Word Word { get; set; }

    /// <summary>
    /// Posts the data to the database async
    /// </summary>
    /// <returns></returns>
    public async Task<IActionResult> OnPostAsync()
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }

        // Get the number of vowels in the word
        Word.Vowels = _wordRepository.NumberOfVowels(Word.Answer);

        // Save the length
        Word.Length = Word.Answer.Length;

        // upload file to blob storage
        Word.Sound = _wordRepository.UploadAudio(WordUpload.SoundFile);

        // save to db
        _context.Word.Add(Word);
        await _context.SaveChangesAsync();
        return RedirectToPage("./Index");
    }
}

页面模板:

@page
@model Fabetio.Web.Pages.Words.CreateModel

@{
    ViewData["Title"] = "Create";
}

<div class="container-fluid darkblue-background">

    <br>
    <br>

    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <div class="task--card">

                <div class="dasboard--title">
                    <h1>@ViewData["Title"]</h1>
                    <p class="subtitle">Subtitle.</p>
                </div>

                <form method="post">
                    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                    <input type="hidden" asp-for="Word.ID" />
                    <div class="form-group">
                        <label asp-for="Word.Answer" class="control-label"></label>
                        <input asp-for="Word.Answer" class="form-control" />
                        <span asp-validation-for="Word.Answer" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="Word.AlternativeAnswer" class="control-label"></label>
                        <input asp-for="Word.AlternativeAnswer" class="form-control" />
                        <span asp-validation-for="Word.AlternativeAnswer" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="Word.Hint" class="control-label"></label>
                        <input asp-for="Word.Hint" class="form-control" />
                        <span asp-validation-for="Word.Hint" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="Word.Language" class="control-label"></label>
                        <input asp-for="Word.Language" class="form-control" />
                        <span asp-validation-for="Word.Language" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="Word.Category" class="control-label"></label>
                        <input asp-for="Word.Category" class="form-control" />
                        <span asp-validation-for="Word.Category" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="Word.Module" class="control-label"></label>
                        <input asp-for="Word.Module" class="form-control" />
                        <span asp-validation-for="Word.Module" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="Word.Difficulty" class="control-label"></label>
                        <input asp-for="Word.Difficulty" class="form-control" />
                        <span asp-validation-for="Word.Difficulty" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="WordUpload.SoundFile" class="control-label"></label>
                        <input asp-for="WordUpload.SoundFile" type="file" class="form-control" />
                        <span asp-validation-for="WordUpload.SoundFile" class="text-danger"></span>
                    </div>

                    <br>
                    <br>

                    <div class="form-group">
                        <input type="submit" value="Create" class="btn btn--blue" />
                    </div>
                </form>
            </div>
        </div>
    </div>
    <br>
    <br>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

WordUpload.SoundFile未与模型一起传递。在调试应用程序时,控制器/页面将其返回为空。所有其他属性都没有任何问题。

你知道如何传递文件吗?


请查看ASP.NET Core中的文件上传,并注意enctype属性。 - Mark G
当表单提交时,它仍然显示 null 而不是文件。你有其他想法吗?为什么会发生这种情况? - krillebimbim
请查看以下教程:在ASP.NET Core的Razor页面中上传文件 - Nkosi
你是否考虑过使用一个模型类?将IFormFile属性合并到一个模型中,它应该可以工作。从文档中,你还应该注意在表单中包含enctype="multipart/form-data" - Nkosi
1个回答

12

你需要在你的表单中添加这个:

<form method="post" enctype="multipart/form-data">
在您的post方法中,如果您遇到了模型绑定未将文件绑定到模型的任何问题,您可以通过Form.Files直接访问它,就像这样:

在您的post方法中,如果您遇到了模型绑定未将文件绑定到模型的任何问题,您可以通过Form.Files直接访问它,就像这样:

 var formFile = HttpContext.Request.Form.Files[0];

您应该先检查HttpContext.Request.Form.Files.Length > 0,否则该代码会抛出错误。然后将字节复制到您的模型以保存。 请参阅文档


我刚试着将它添加到表单中,但当我尝试提交表单时,该属性仍然为空。您有任何其他想法是什么原因导致的吗? - krillebimbim
@JoeAudette 我不认为你说的是真的,对于 IFormFile 的模型绑定应该可以正常工作。我猜测 multipart/form-data 实际上就是解决方法。 - Henk Mollema
@HenkMollema,你说得对,文档看起来应该是可以工作的,但是操作者说这并没有解决问题。我会编辑我的回答,如果您在文件模型绑定方面遇到任何问题,您可以直接从Form.Files获取它。 - Joe Audette
啊,我明白了,那很奇怪。感谢您的澄清。 - Henk Mollema

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接