【问题标题】:ASP.Net Core Populating Dropdown with List Model itemASP.Net Core 使用列表模型项填充下拉列表
【发布时间】:2019-11-15 16:31:03
【问题描述】:

我正在尝试填充“公司”下拉列表,但无法正确获取 Razor 语法。 使用下面的代码,它使我的模态不会弹出。 JS 收到公司字段的未定义错误并出错。如果我删除@Html.DropDownListFor(c => c.SelectedCompany, Model.CompanyLists, "- Please select a state -", new { @class = "form-control" }),那么模式会很好地弹出,只是没有填充任何项目。

知道我做错了什么吗?我正在使用这篇文章作为参考。 https://nimblegecko.com/using-simple-drop-down-lists-in-ASP-NET-MVC/ ;但是,它有一个硬编码列表,而不是从 DB 中提取的列表。

 <div class="tab-pane fade show active" id="user" role="tabpanel" aria-labelledby="user-tab">
   <form method="post" class="mt-3">
      <div class="form-group row text-center">
         <label asp-for="Id" class="col-sm-3 text-right col-form-label labelFont"></label>
           <div class="col-sm-8">
             <input disabled asp-for="Id" class="formField inputDisabled" disabledclass="form-control">
           </div>
      </div>
      <div class="form-group row text-center">
        <label asp-for="FirstName" class="col-sm-3 text-right col-form-label labelFont"></label>
          <div class="col-sm-8">
            <input asp-for="FirstName" class="formField" />
              <span asp-validation-for="FirstName" class="text-danger"></span>
          /div>
      </div>
      <div class="form-group row text-center">
        <label asp-for="LastName" class="col-sm-3 text-right col-form-label labelFont"></label>
          <div class="col-sm-8">
            <input asp-for="LastName" class="formField" />
              <span asp-validation-for="LastName" class="text-danger"></span>
          </div>
      </div>
      <div class="form-group row text-center">
        <label asp-for="Title" class="col-sm-3 text-right col-form-label labelFont"></label>
          <div class="col-sm-8">
            <input asp-for="Title" class="formField" />
              <span asp-validation-for="Title" class="text-danger"></span>
          </div>
      </div>
      <div class="form-group row text-center">
        <label asp-for="Email" class="col-sm-3 text-right col-form-label labelFont"></label>
          <div class="col-sm-8">
            <input asp-for="Email" class="formField" />
              <span asp-validation-for="Email" class="text-danger"></span>
          </div>
      </div>
      <div class="form-group row text-center">
        <label asp-for="UserName" class="col-sm-3 text-right col-form-label labelFont"></label>
          <div class="col-sm-8">
            <input asp-for="UserName" class="formField" />
              <span asp-validation-for="UserName" class="text-danger"></span>
          </div>
      </div>
      <div class="form-group row text-center">
        <label asp-for="CompanyLists" class="col-sm-3 text-right col-form-label labelFont"></label>
@*ISSUE IS HERE--------------------------------------------------------------------------------------*@
          <div class="col-md-5">
            @Html.DropDownListFor(c => c.SelectedCompany, Model.CompanyLists, "- Please select a state -", new { @class = "form-control" })
            @Html.ValidationMessageFor(c => c.SelectedCompany, "", new { @class = "text-danger" })
          </div>
@*------------------------------------------------------------------------------------------*@
      </div>
      <div class="form-group row text-center">
        <label asp-for="Address" class="col-sm-3 text-right col-form-label labelFont"></label>
          <div class="col-sm-8">
            <input asp-for="Address" class="formField" />
              <span asp-validation-for="Address" class="text-danger"></span>
          </div>
      </div>
      <div class="form-group row text-center">
        <label asp-for="City" class="col-sm-3 text-right col-form-label labelFont"></label>
          <div class="col-sm-8">
            <input asp-for="City" class="formField" />
              <span asp-validation-for="City" class="text-danger"></span>
          </div>
      </div>
      <div class="form-group row text-center">
        <label asp-for="State" class="col-sm-3 text-right col-form-label labelFont"></label>
          <div class="col-sm-8">
            <input asp-for="State" class="formField" />
              <span asp-validation-for="State" class="text-danger"></span>
          </div>
      </div>

      <div asp-validation-summary="All" class="text-danger"></div>
        <button type="submit" class="btn btn-primary padFloat btnBlue" asp-action="EditUser" asp-controller="Administration" asp-route-id="@Model.Id">Update</button>
        <a asp-action="UserMaint" class="btn btn-primary padFloat btnRed">Cancel</a>
 </form>
</div>

型号:

namespace PortalDev.Models.ViewModels
{
    public class EditUserViewModel
    {

        public EditUserViewModel()
        {
            Claims = new List<Claim>();
            Roles = new List<Role>();
            //CompanyLists = new List<ICompanyRepository>();
            CompanyLists = new List<CompanyList>();
        }

        //ROLES ---------------------------------------------
        public class Role
        {
            public string RoleName { get; set; }
            public string RoleID { get; set; }
            public bool IsSelected { get; set; }

        }
        public List<Role> Roles { get; set; }

        //CLAIMS----------------------------------------------
        public class Claim
        {
            public string ClaimType { get; set; }
            public string ClaimID { get; set; }
            public bool IsSelected { get; set; }
        }
        public List<Claim> Claims { get; set; }

        //COMPANY DROPDOWN--------------------------------------
        public class CompanyList
        {
            public string CompanyName { get; set; }
            public int CompanyID { get; set; }
        }
        [Display(Name = "Company")]
        public List<CompanyList> CompanyLists { get; set; }   //List of Companies for dropdown
        public string SelectedCompany { get; set; }

        //USER INFORMATION --------------------------------------
        public string Id { get; set; }
        //[Required]
        public string UserName { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Title { get; set; }
        [Required]
        [EmailAddress]
        public string Email { get; set; }
        public string Address { get; set; }
        public string City { get; set; }
        public string State { get; set; }                            
    }     
}

方法:

// EDIT USER : GET-----------------------------------------------------
        [HttpGet]
        public async Task<IActionResult> EditUser(string id)
        {
            //GET USER INFORMATION - EXIT IF USER DOESN'T EXIST
            var user = await userManager.FindByIdAsync(id);
            if (user == null)
                {
                ViewBag.ErrorMessage = $"User with Id = {id} cannot be found";
                return View("NotFound");
            }             

            //USER INFORMATION ---------------------------------------
            var model = new EditUserViewModel
            {
                Id = user.Id,
                Email = user.Email,
                UserName = user.UserName,
                FirstName = user.FirstName,
                LastName = user.LastName,
                Title = user.Title,
                Address = user.Address,
                City = user.City,
                State = user.State,
                //CompanyId = user.CompanyId

            };

            //   ViewBag.SelectedCommpany = user.CompanyId;

            //COMPANY DROPDOWN INFO------------------------------------
            var company = from c in companyRepository.GetCompanys() select c;
            foreach (var c in company)
            {
                ////Store this inforamtion into the company list in the viewmodel
                var companyinfo = new EditUserViewModel.CompanyList
                {
                    CompanyName = c.CompanyName,
                    CompanyID = c.CompanyId
                };
                model.CompanyLists.Add(companyinfo);
            };

            //GET LIST OF ROLES(RoleID, RoleName)
            var roles = roleManager.Roles;

            foreach (var RoleName in roles)
            {
                //Execute identity method to get full information for the Role and store into an object (roleinfo)
                var roleString = RoleName.Name;
                var fullRoleInfo = await roleManager.FindByNameAsync(roleString);
                //Store this information into the Role list in the viewmodel
                var roleinfo = new EditUserViewModel.Role
                {
                    RoleName = fullRoleInfo.Name,
                    RoleID = fullRoleInfo.Id,
                };

                if (await userManager.IsInRoleAsync(user, roleString))
                {
                    roleinfo.IsSelected = true;
                }
                else
                {
                    roleinfo.IsSelected = false;
                }                

                model.Roles.Add(roleinfo);
            };

            //**************************************************************************************************************************************************************
            //IDENTITY CLAIM INFORMATION ------------------------------

            var existingUserClaims = await userManager.GetClaimsAsync(user);

            foreach (Claim claim in ClaimStore.AllClaims)
            {
                var userClaims = new EditUserViewModel.Claim
                {
                    ClaimType = claim.Type
                };


                if (existingUserClaims.Any(c => c.Type == claim.Type && c.Value == "true"))
                {
                    userClaims.IsSelected = true;
                }
                else
                {
                    userClaims.IsSelected = false;
                }

                model.Claims.Add(userClaims);
            }
            ViewBag.UserModel = model;
            return PartialView("~/Views/Modals/_EditUserModalPartial.cshtml", model);
        }

【问题讨论】:

  • 仅供参考,我不会使用 viewbag 作为填充 ViewModel 的方法。非常糟糕的练习。请阅读该主题。通过存储在 viewbag 中,您正在消除 ASP.NET MVC 剃须刀引擎的优势。我可能也会稍微清理一下视图模型。
  • 你调试EditUser ActionResult了吗? Id 逐步检查它并确定 GetCompanies 是否从存储库返回 List&lt;CompanyList&gt;
  • @S.Kellar 这是关于计数的 GTK。所以是的,你说得对,它可能是 Razor 语法,但更重要的是,我会用实际返回的模型替换 ViewBag。我敢打赌你的问题会得到解决。 ViewBagViewData 用于为异常传递临时数据(即:非模型数据)。我尽量不要使用它们,除非我必须这样做,
  • 实际上再看一遍,您将模型传递给局部视图,但您也将模型存储在ViewBag.UserModel 中。我会从那里开始
  • @yardpenalty ,我拿出了那个 viewbag ,一切仍然正常(减去原始问题)。正在尝试进行建议的更改

标签: c# asp.net asp.net-mvc razor


【解决方案1】:

按照我的例子

这是我的 DropDownListFor;

  @Html.DropDownListFor(model => Model.SelectedDropDownValue, new SelectList(Model.DropDownListAutoPopulate), "Quarter - Year", new { @class = "form-control btn-primary form-control", @id = "QuarterYearConcat", @onchange = @"form.submit();" })

Model.SelectedDropDownValue 是从控制器传回的选定值

public List<string> DropDownListAutoPopulate { get; set; } 

是将填充下拉列表的列表。这是我的 viewModel 模型。

这是我的 viewModel 的完整模型

namespace MoCApp.ViewModels
{
    public class SLGAdminCreateViewModel
    {
        public SLGHeader SLGHeader;
        [Range(-100.00, 100.00, ErrorMessage = "Value must be between -100 and 100")]
        public decimal? TotalBudget { get; set; }
        [Range(-100.00, 100.00, ErrorMessage = "Value must be between -100 and 100")]
        public decimal? TotalLaborBudget { get; set; }

        public List<QuarterWeekType> DropDownList { get; set; }

        public SLGQuarterDetails SLGQuarterList { get; set; }

        public QuarterWeekType Dropdown { get; set; }

        public string SelectedDropDownValue { get; set; }

        public List<string> DropDownListAutoPopulate { get; set; }
    }
}

这是我与模型和视图相关的 Get 方法。

  // GET: SLG/CreateAdmin
    [Authorize(Roles = "WFL_APP_MOCHUB-Admins,WFL_APP_SLG-Admins,Managers,WFL_ROLE_StoreManagmentTeams")]
    public ActionResult CreateAdmin(SLGAdminCreateViewModel value)
    {
        // ViewModel for Both Forms
        var viewModel = new SLGAdminCreateViewModel
        {
            SLGHeader = new SLGHeader(),
            DropDownList = new List<QuarterWeekType>(),
            DropDownListAutoPopulate = new List<string>(),
            TotalBudget = null,
            TotalLaborBudget = null
        };
        // Formating returned value for query to set values.
        if (value.SelectedDropDownValue != null)
        {
            var QuarterYear = value.SelectedDropDownValue.Replace("Q", "").Replace(":", "").Replace(" ", "");
            var Quarter = decimal.Parse(QuarterYear.Substring(0, 1), CultureInfo.InvariantCulture);
            var Year = decimal.Parse(QuarterYear.Substring(1, 4), CultureInfo.InvariantCulture);
            var TotalBudgetList = db.QuarterDetails.Where(x => x.Quarter == Quarter && x.Year == Year && x.Store == 1 && x.Department == "total")
                .ToList();
            foreach (var x in TotalBudgetList) { viewModel.TotalBudget = x.TotalBudget; viewModel.TotalLaborBudget = x.TotalLaborBudget; };
        }
        // Format dropdown list
        viewModel.DropDownList = db.SLGHeaderTemplates.Where(x => x.Year > 2018 && x.Week == 1).Select(x => new QuarterWeekType { Year = x.Year, Quarter = x.Quarter, QuarterYearConcat = "" }).ToList();
        foreach (var item in viewModel.DropDownList)
        {
            item.QuarterYearConcat = "Q" + Convert.ToInt32(item.Quarter) + " : " + Convert.ToInt32(item.Year);
        }
        foreach (var x in viewModel.DropDownList) { viewModel.DropDownListAutoPopulate.Add(x.QuarterYearConcat); };

        return View(viewModel);
    }

如果你按照我的例子,让你的模型、视图和控制器处于相同的关系中。你会是金色的。

不要介意我的逻辑,我遍历一个对象并将其放入另一个列表。只需知道您的列表在 DropDownListFor 语句中的位置以及它与您的 viewModel 和 Controller 的关系。

【讨论】:

  • 我的耳朵还是湿透了.....这个例子是压倒性的。我可以将其中的一些拼凑起来,但我不知道如何将其应用于我的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多