Заполнение и выбор значения раскрывающегося списка в ASP.NET MVC 4

Выпадающие списки в ASP.NET MVC смущают меня. У меня есть модельный класс. В классе модели есть строка SelectedValue. Эта строка представляет это ранее выбранное значение. У меня есть коллекция предметов, которые я вытащил из базы данных. Каждый элемент коллекции имеет идентификатор и значение имени. Моя проблема в том, что я не знаю, каков рекомендуемый способ получения этой информации в пользовательском интерфейсе.

Я не уверен, должен ли я использовать ViewBag или Модель. Как только значение будет там, я даже не уверен, каков наилучший способ заполнить пользовательский интерфейс. Я видел помощников HTML и людей, использующих синтаксис RAZOR. Я очень смущен. Что люди рекомендуют?

Спасибо

4 ответа

Решение

Вот как я это делаю, скажем, у вас есть 2 модели Team and Player:

Player.cs

public class Player
{
    [HiddenInput(DisplayValue = false)]
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }        

    [Required]
    [ForeignKey("Team")]
    [Display(Name = "Team")]
    public int TeamId { get; set; }        

    [Display(Name = "First name")]
    public string FirstName { get; set; }

    [Display(Name = "Last name")]
    public string LastName { get; set; }

    public virtual Team Team { get; set; }        
}

Team.cs

 public class Team
{
    [Key]
    [HiddenInput(DisplayValue = false)]
    public int TeamId { get; set; }

    [Display(Name = "Full Name:")]
    public string Name { get; set; }        

    public virtual ICollection<Player> Players { get; set; }
}

Затем в вашем PlayerController:Примечание: команда должна существовать, чтобы создать игрока

    private void PopulateTeamsDropDownList(object selectedTeams = null)
    {
        var teamsQuery = from d in _dataSource.Teams
                         orderby d.Name
                         select d;
        ViewBag.TeamID = new SelectList(teamsQuery, "TeamId", "Name", selectedTeams);
    }

    [HttpGet]
    public ActionResult Create()
    {
        PopulateTeamsDropDownList();
        return View();
    }

    [HttpPost]
    public ActionResult Create(Player model)
    {
        if (ModelState.IsValid)
        {
            using (EFootballDb db = new EFootballDb())
            {
                try
                {
                    var player = new Player
                                     {
                                         FirstName = model.FirstName,
                                         LastName = model.LastName
                                     };
                    db.Players.Add(player);
                    db.SaveChanges();
                    return RedirectToAction("About", "Home");
                }
                catch (Exception)
                {
                    ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
                }
            }
        }
        PopulateTeamsDropDownList(model.TeamId);
        return View(model);
    }

И, наконец, ваш Create View for Player будет выглядеть так:

@{
ViewBag.Title = "Create";
 }

<h2>Create</h2>

@using (Html.BeginForm()) {
@Html.ValidationSummary(true)

<fieldset>
    <legend>Player</legend>

    <div class="editor-label">
            @Html.LabelFor(model => model.TeamId, "Pick Your Team")
    </div>
    <div class="editor-field">
        @Html.DropDownList("TeamId", String.Empty)
        @Html.ValidationMessageFor(model => model.TeamId)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.FirstName)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.FirstName)
        @Html.ValidationMessageFor(model => model.FirstName)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.LastName)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.LastName)
        @Html.ValidationMessageFor(model => model.LastName)
    </div>        

    <p>
        <input type="submit" value="Create" />
    </p>
  </fieldset>
 }

 <div>
     @Html.ActionLink("Back to List", "Index")
 </div>

 @section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

То, как я это делаю, делает раскрывающийся список частью моей ViewModel.... скажем, это продукты.... так что в моей ViewModel у меня есть

public SelectList Products { get; set;}
public int ProductId { get; set; }  // For the the selected Product

Поэтому, когда представление загружается, и я заполняю модель, чтобы вернуться к представлению в контроллере, я делаю что-то вроде этого:

model.Products = new SelectList(MyEnumerableofProducts, "ValueField", "TextField", {value of the selected item in the dropdown, as a string)

На мой взгляд, я бы имел:

@Html.DropDownListFor(model => model.ProductId, Model.Products, "Please Select")



return View(model)

В дополнение к описанным выше методам, вы также можете использовать этот подход для использования нескольких внешних ключей в таблице поиска. Это очень ясно и эффективно, насколько я видел.

Если вы используете VB.Net - MVC4- Razor Этот ответ почти такой же, как Frigik(спасибо Frigik)

В вашей модели создайте два поля: одно - это поле, в котором будет храниться SelectedItem(здесь это TagType of string), а второе - раскрывающиеся значения (TagTypeList).

Модельный класс- Tag.vb

Imports System.Web.Mvc

Private _tagType As String
Private _tagTypeList As List(Of SelectListItem)

Public Property TagType() As String
        Get
            Return _tagType
        End Get
        Set(ByVal value As String)
            _tagType = value
        End Set
End Property

Public Property TagTypeList() As List(Of SelectListItem)
        Get
            Return _tagTypeList
        End Get
        Set(value As List(Of SelectListItem))
            _tagTypeList = value
        End Set
    End Property

'In the constructor

Sub New()
        TagTypeList = CommonUtility.LoadDropDownByName("TAGTYPE")
End Sub

В классе CommonUtility - CommonUtility.vb

Imports System.Web.Mvc
Imports System.Collections.Generic


Public Shared Function LoadDropDownByName(ByVal DropDownName As String) As List(Of SelectListItem)
        Dim dt As DataTable
        Dim ds As DataSet
        Dim results As List(Of SelectListItem) = Nothing
        Try
            ds = objSignOn.LoadDropDown(DropDownName)   'Pass the dropdown name here and get the values from DB table which is - select ddlId, ddlDesc from <table name>
            If Not ds Is Nothing Then
                dt = ds.Tables(0)
                If (dt.Rows.Count > 0) Then
                    results = (From p In dt Select New SelectListItem With {.Text = p.Item("ddlDesc").ToString(), .Value = p.Item("ddlId").ToString()}).ToList()
                End If
            End If
        Catch ex As Exception
        End Try
        Return results
    End Function

В представлении

@Html.DropDownListFor(Function(x) x.TagType, Model.TagTypeList, "", New With {.id = "ddlTagType",.class = "dropDown", .style = "width: 140px"})

Здесь 3-й параметр (необязательно) как пустой, который будет вставлять 1-й элемент как пустой в раскрывающемся списке. Первым параметром является selectedItem, который помогает заполнить, когда значение уже присутствует в таблице БД.

Надеюсь, это поможет тем, кто использует VB.Net

Другие вопросы по тегам