【问题标题】:Selected item not return value asp.net MVC所选项目不返回值 asp.net MVC
【发布时间】:2021-09-19 11:27:39
【问题描述】:

我有这个模型,并且表 i db 有数据

public class FileType
    {
        public int Id { get; set; }

        public string FileTypeName { get; set; }
    }

我有上传表单和这个视图模型供上传

 public List<FileModel> Files { get; set; }
        public string Name { get; set; }
        public string Extension { get; set; }
        public string Description { get; set; }
        public string Author { get; set; }
        public string Year { get; set; }
        public string FilePath { get; set; }
        public string PublishedOn { get; set; }
        public int DownloadCounter { get; set; }
        public Genres Genre { get; set;}
        public int FileTypeId { get; set; }
        public List<SelectListItem> FtypeList { get; set; }
        public FileType FileT { get; set; }

我使用此代码生成下拉列表以选择 FileType:

 public  IActionResult Index()
        {
            var vm = new FileUploadViewModel();
            vm.FtypeList = context.FileTypes
                .Select(a => new SelectListItem()
            {
                Value = a.Id.ToString(),
                Text=a.FileTypeName
            }).ToList();

            ViewBag.Message = TempData["Message"];
            return View(vm);
        }

我认为我有这个

<div class="form-group row">
        <label asp-for="FileT" class="col-sm-2 col-form-label"> </label>
        <div class="col-sm-10">
            <select asp-for="FileT" class="custom-select mr-sm-2" asp-items="@Model.FtypeList"></select>
        </div>
        </div>

在 HttpPost 操作中我这样做

[HttpPost]
        public async Task<IActionResult> Index(List<IFormFile> files, string description,DateTime PublishedOn,string Author,string Name,FileType Ftype)
        {
            foreach (var file in files)
            {
                var basePath = Path.Combine(Directory.GetCurrentDirectory() + "\\Files\\");
                bool basePathExists = System.IO.Directory.Exists(basePath);
                if (!basePathExists) Directory.CreateDirectory(basePath);
                var fileName = Path.GetFileNameWithoutExtension(file.FileName);
                var filePath = Path.Combine(basePath, file.FileName);
                var extension = Path.GetExtension(file.FileName);
               
                DateTime dateTime = DateTime.UtcNow;
                var createdOn = dateTime.ToShortDateString();
                if (!System.IO.File.Exists(filePath))
                {
                    using (var stream = new FileStream(filePath, FileMode.Create))
                    {
                        await file.CopyToAsync(stream);
                    }
                    var fileModel = new FileModel
                    {
                        Year =createdOn,
                        PublishedOn = PublishedOn.ToShortDateString(),
                        FileType = file.ContentType,
                        Extension = extension,
                        Name = Name,
                        Description = description,
                        FilePath = filePath,
                        Author=Author,
                        Ftype=Ftype,
                    };
                    context.Files.Add(fileModel);
                    context.SaveChanges();
                }
            }
            TempData["Message"] = "File successfully uploaded to File System.";
            return RedirectToAction("Index","Home");
        } 

但是当我上传文件时,它不会从下拉列表中获取选定的值,它会在选定的列表中创建新项目。例如,如果我在文件上传到数据库时选择值为 3 的项目,则表中只有 4 个文件类型上传文件 Ftype = 5 的表,并在 Id = 5 的 FileTypes 表中创建新行。

【问题讨论】:

  • 我不清楚您从视图中摘录的内容与发布操作有何关联。在您的代码中,您使用asp-for="FileT",这意味着将发送名称为FileT 的表单数据(这将是一个int,因为您使用FileType.Id 作为值)。但在行动中,你期待的是FileType FType
  • 我有一个名为 FileModel 的主模型,我在这里传递 context.Files.Add(fileModel);所以在那个模型中,我想从下拉列表中保存选定的 FileType 及其公共 FileType Ftype。它应该是 int FtypeID 而不是 FileType Ftype 并在 post 方法中像整数一样保存它?

标签: c# asp.net asp.net-mvc postgresql asp.net-core


【解决方案1】:

修复您的视图,您必须使用 FileTypeId 进行选择

 <select asp-for="FileTypeId" class="custom-select mr-sm-2" asp-items="@Model.FtypeList"></select
......

由于您使用的是 post,因此您的操作输入参数应该与模型相同

 public async Task<IActionResult> Index(FileModel viewModel)
   ......

【讨论】:

  • 我在使用此模型创建的表中上传带有索引操作的文件,哪种类型应该是流派和文件类型的列?
  • @DevGary 对不起,我没有注意到你有 FileTypeId 。我更新了我的答案。您必须将 FileT 保留在您的视图模型中。我不能告诉任何关于流派的信息,因为我看不到课程,但可能你也必须添加流派 ID。
  • 当我在文件模型的后期操作中创建文件模型时,我有这个
【解决方案2】:

根据您的 FileUploadViewModel 视图模型,我假设 FileTypeId 是用户选择的文件类型 ID 值,对吧?

如果是这样的话,我建议你可以修改你的代码如下:

<div class="form-group row">
    <label asp-for="FileTypeId" class="col-sm-2 col-form-label"> </label>
    <div class="col-sm-10">
        <select asp-for="FileTypeId" class="custom-select mr-sm-2" asp-items="@Model.FtypeList"></select>
    </div>
</div>

然后,在 action 方法中添加 FileTypeId 参数,如下所示:

[HttpPost]
public async Task<IActionResult> CreateFile(List<IFormFile> files, string description, DateTime PublishedOn, string Author, string Name, FileType Ftype, int FileTypeId)
{

然后,当您创建 FileModel 时,您可以根据 FileTypeId 参数检查 FileType 是否存在。检查以下代码:

var fileModel = new FileModel
{
    Year =createdOn,
    PublishedOn = PublishedOn.ToShortDateString(),
    FileType = file.ContentType,
    Extension = extension,
    Name = Name,
    Description = description,
    FilePath = filePath,
    Author=Author, 
};

//Check if the FileType exists or not, if exists, get the existing FileType and assign it to the new fileModel. if not exists, create a new FileType Model and assign it to the new fileModel.
var filetype = context.FileTypes.Where(c => c.Id == FileTypeId).FirstOrDefault() 
if (filetype!= null)
{
    fileModel.Ftype = filetype; //using the existing file type.
}
else
{
    var newFileType = new FileType();
    fileModel.Ftype = newFileType ; //using the new file type.
}
context.Files.Add(fileModel);
context.SaveChanges();
FileType = file.ContentType,

另外,好像FileModel中也包含FileType,不知道是不是这个问题,如果你使用Ftype属性来设置文件类型,或许不需要设置FileType属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    • 2013-12-02
    • 1970-01-01
    相关资源
    最近更新 更多