繁体   English   中英

ASP.NET CORE,查看 model 的所有字段为 null 时传递回 Z9BBF373797BF7CF7BA62C80023

[英]ASP.NET CORE, View model has all fields as null when passed back to Controller

我正在尝试让简单的 ASP.NET CORE web 应用程序运行,我遇到了允许用户通过 html 链接访问我服务器上的文件的问题。 我有一个名为“TestModel”的 model、一个名为“TestView”的视图和一个名为“AppController”的 controller。 我的视图允许用户在两个单独的字段中输入一些文本以及 select 从他们的硬盘驱动器中输入两个不同的文件,它将所有内容绑定到我的 model 并在用户单击按钮时执行 POST。 我已验证 model 已正确传递回我的 controller。 我的 controller 正确地将文件保存到我的服务器目录中的文件夹中,使用单独的服务来操作文件,并将 model 返回到视图,即当我使用调试器检查 Testview 中的“返回视图(模型)”时操作 model 被传回具有填充的所有属性。

问题是我希望视图上的两个链接指向服务器上的文件,以便用户可以单击链接并收到下载文件的提示,但我似乎无法继续。 I am using the @Html.ActionLink() capability in razor to point to a "Download descriptions" action and pass the model to it, thinking that it would be passing the current view's model, but the model it passes has all fields as null . 对我做错了什么有任何见解吗?

这些是我的 AppController 中的相关操作:

        [HttpPost("~/App/TestView")]
        public IActionResult TestView(TestModel Model)
        {
            if (ModelState.IsValid)
            {
                Console.WriteLine("Something was sent back from the TestView page");
                Model.OnPostAsync();
                var x = _descLogicService.Convert(Model);
            }

            return View(Model);
        }

        public IActionResult DownloadDescriptions(TestModel model)
        {
            var cd = new ContentDispositionHeaderValue("attachment")
            {
                FileNameStar = model.DescriptionFile.FileName
            };

            Response.Headers.Add(HeaderNames.ContentDisposition, cd.ToString());

            byte[] bytes = System.IO.File.ReadAllBytes(model.MeasurementExportFile);

            using (FileStream fs = new FileStream(model.MeasurementExportFile, FileMode.Open, FileAccess.Read))
            {
                fs.Read(bytes, 0, System.Convert.ToInt32(fs.Length));
                fs.Close();
            }

            return File(bytes, "text/csv");

        }

这是我的视图 Model:

 public class TestModel
    {
        [BindProperty]
        [Required]
        [MinLength(5)]
        public string Name { get; set; }
        [BindProperty]
        [Required]
        [MaxLength(10,ErrorMessage ="Input string is too long.")]
        public string MyInput { get; set; }

        [BindProperty]
        [Required]
        public IFormFile DescriptionFile { get; set; }


        [BindProperty]
        [Required]
        public IFormFile MeasurementFile { get; set; }
        public string DescriptionDirectory { get; set; } 
        public string DescriptionExportFile { get; set; } 
        public string MeasurementDirectory { get; set; } 
        public string MeasurementExportFile { get; set; }

        public async Task OnPostAsync()
        {
            var token = DateTime.Now.Ticks.ToString();

            var directory =  Directory.CreateDirectory(@"uploads\"+ token + @"\");
            DescriptionDirectory = directory.CreateSubdirectory("Descriptions").FullName + @"\";
            DescriptionExportFile = directory.CreateSubdirectory(@"Descriptions\Exports\").FullName + DescriptionFile.FileName;
            MeasurementDirectory = directory.CreateSubdirectory("Measurements").FullName + @"\";
            MeasurementExportFile = directory.CreateSubdirectory(@"Measurements\Exports\").FullName + MeasurementFile.FileName;

            var file = Path.Combine(DescriptionDirectory, DescriptionFile.FileName);
            using (var fileStream = new FileStream(file, FileMode.Create))
            {
                await DescriptionFile.CopyToAsync(fileStream).ConfigureAwait(true);
            }

             file = Path.Combine(MeasurementDirectory, MeasurementFile.FileName);
            using (var fileStream = new FileStream(file, FileMode.Create))
            {
                await MeasurementFile.CopyToAsync(fileStream).ConfigureAwait(true);
            }
        }
    }

这是视图:

@**I need to add the namespace of C# models I'm creating *@
@using FirstASPNETCOREProject.ViewModels
@*I need to identify the model which 'fits' this page, that is the properties of the model can be
    bound to entities on the view page, using "asp-for"*@
@model TestModel
@{
    ViewData["Title"] = "Page for File Uploads";
}
@section Scripts{
}

<div asp-validation-summary="ModelOnly" style="color:white"></div>
<form method="post" enctype="multipart/form-data">
    <label>Enter a Description File Name</label>
    <input asp-for="Name" type="text" />
    <span asp-validation-for="Name"></span>
    <br>
    <label>Select a Description File</label>
    <input asp-for="DescriptionFile" type="file" />
    <span asp-validation-for="DescriptionFile"></span>
    <br>
    <label>Enter the Measurement File Name</label>
    <input asp-for="MyInput" type="text">
    <span asp-validation-for="MyInput"></span>
    <br>
    <label>Select a Measurement File</label>
    <input asp-for="MeasurementFile" type="file">
    <span asp-validation-for="MeasurementFile"></span>
    <br>
    <input type="submit" value="Send Message" />
</form>


@Html.ActionLink("Description File", "DownloadDescriptions", "App")
@Html.ActionLink("Measurement File", "DownloadMeasurements", "App")

ActionLink 只是锚标记。

所以他们使用GET。 因此,要使用 get 传回您的 model,您需要使用查询字符串参数,例如在 url 末尾添加“?MyInpu = some cool input”。

您可以像这样绑定几乎任何复杂的 object,包括列表和 Arrays。

有关Model 绑定的更多信息

文件本身你将无法像那样传递它。 为此,您需要使用 javascript 使用提交按钮或 FormData 发布表单。

您还可以添加调用 javascript 函数的锚点,这些函数使用 AJAX 将您想要的所有内容回发到 controller 中的 DownloadDescriptions 操作。

以下是有关如何使用操作链接传递 model 的示例:

 @Html.ActionLink("Test Action", "TestAction", "Home", new { myInput = "Some Cool Input" })

在我的例子中,之前的 ActionLink 生成了一个带有 href 设置为的锚标记:

http://localhost:64941/Home/TestAction?myInput=Some Cool Input

请注意我如何使用匿名类型来传递 model 使用与我的 model 的属性相同的名称(在这种情况下为 MyInput但在骆驼化版本myInput中)。

您可以像这样组合任何 model。

这是我在 controller 中的操作:

    public IActionResult TestAction([FromQuery]TestModel input) 
    {
        return View(input);
    }

请注意我如何使用 [FromQuery] 作为TestModel参数来表明我期望 ASP.NET 核心 model 绑定器使用查询字符串参数来填充我的 model。

这是我的 model class:

public class TestModel
{
    public string MyInput { get; set; }
}

这是调试期间的结果:

在此处输入图像描述

请注意在调试期间我如何能够看到填充的值。

笔记:

如果您的 model 在客户端发生变化。 您将需要使用 javascript... 更新锚标记中的查询字符串参数...因此,将名称添加到锚标记是一个好主意。

这也可能会回答您的问题,但可能不是您尝试做的最佳方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM