Как связать Html.DropDownList без ViewData (строго типизированное представление) - PullRequest
3 голосов
/ 21 мая 2009

Кажется, я не могу найти хороший пост в блоге, в котором показано, как связать модель с видом без волшебных строк "ViewData" (использование подхода со строгим типом - это подход, который я пытаюсь использовать) *

Кто-нибудь знает, что мне нужно изменить ниже, чтобы связать это напрямую с моей моделью?

View

<%@ Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of IEnumerable (Of MvcApplication1.Category))" %>
<asp:Content ID="aboutContent" ContentPlaceHolderID="MainContent" runat="server">
    <%=Html.DropDownList("CategoryList")%>
</asp:Content>

Контроллер

Function Index() As ActionResult
    Dim list As New List(Of Category)
    list.Add(New Category With {.CategoryID = 1, .CategoryName = "Test1"})
    list.Add(New Category With {.CategoryID = 2, .CategoryName = "Test2"})

    Return View()
End Function

EDIT

Окончательное решение в VB показано ниже, спасибо за большой отклик!

Контроллер

Function Index() As ActionResult
    Dim id As Integer = 1
    Dim ProductObject As Product = mProductService.GetProductById(id)

    Return View(ProductObject)
End Function

View

<%=Html.DropDownList("Category", New SelectList(Model.Categories, "CategoryID", "CategoryName"))%>

Класс продукта (без свойства IEnumeralbe для категорий)

Public Class Product
    Public Sub New()

    End Sub


    Private mProductID As Integer
    Public Property ProductID() As Integer
        Get
            Return mProductID
        End Get
        Set(ByVal value As Integer)
            mProductID = value
        End Set
    End Property

    ReadOnly Property Categories() As IEnumerable(Of Category)
        Get
            Dim list As New List(Of Category)
            list.Add(New Category With {.CategoryID = 1, .CategoryName = "Test1"})
            list.Add(New Category With {.CategoryID = 2, .CategoryName = "Test2"})

            Return list
        End Get
    End Property

End Class

Ответы [ 3 ]

5 голосов
/ 21 мая 2009

Помощник раскрывающегося списка принимает IEnumerable<SelectListItem>, а не IEnumerable<Category>. Как правило, ваша страница имеет определенную модель. Модель включает в себя свойство для выбранного значения из раскрывающегося списка, а не коллекции. Вы предоставляете коллекцию для выбора через ViewData. У вас может быть модель только для просмотра, которая включает в себя как свойства, так и набор (ы) для выбора, но это может означать увеличение количества классов. Есть некоторые споры относительно того, являются ли распространяющиеся классы или магические струны худшим дизайном.

Мой код будет выглядеть примерно так:

<%@ Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of Foo)" %>
<asp:Content ID="aboutContent" ContentPlaceHolderID="MainContent" runat="server">
    <%=Html.DropDownList("Category", ViewData("CategoryList"))%>
</asp:Content>

Function Index() As ActionResult
    Dim list As New List(Of SelectListItem)
    list.Add(New SelectListItem  With {.Value = 1, .Text = "Test1"})
    list.Add(New SelectListItem With {.Value = 2, .Text = "Test2"})
    ViewData("CategoryList") = list
    Return View()
End Function

где Foo - это класс, который содержит свойство Category типа int.

Если вы хотите сделать строго типизированное представление, то у Foo есть свойство Categories типа типа SelectListItem, затем измените:

<%=Html.DropDownList("Category", ViewData("CategoryList"))%>

до

<%=Html.DropDownList("Category", Foo.Categories )%>

и

    ViewData("CategoryList") = list
    Return View()

до

    Dim foo as New Foo
    foo.Categories = list
    Return View(foo)
1 голос
/ 21 мая 2009

Вы можете создать свою собственную перегрузку вспомогательного метода для Html.DropDownList, которая будет напрямую сопоставлять модель с помощником DropDownList.

При этом вы должны спросить себя, сколько доменной логики должно содержать ваше представление. ViewData помогает отделить вашу модель и доменную логику от вашего представления.

Пример:

Я знаю, что это не «перегрузка», потому что чувствовалось, что, поскольку для этого все еще потребуется имя, вам нужен другой метод, который просто берет строку для имени выпадающего списка, но автоматически связывает модель с элементом управления (при условии это IEnumerable). Это пример метода расширения HtmlHelper.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;

namespace MvcApplication3.Helpers
{
    public static class ViewHelpers
    {
        public static string ModelDropDownList(this HtmlHelper htmlHelper, string name)
        {
            var model = htmlHelper.ViewData.Model as IEnumerable<SelectListItem>;
            if(model == null)
                return string.Empty;

            return htmlHelper.DropDownList(name, model);
        }
    }
}

Вот как вы бы назвали это, по вашему мнению

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<SelectListItem>>" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <%= Html.ModelDropDownList("Test") %>
</asp:Content>
0 голосов
/ 21 мая 2009

Если вы хотите использовать метод Strongly Typed, есть объект SelectList, в который вы можете передать IEnumerable. Вы должны указать свойства Text Field и Value Field для T, но этот объект SelectList может быть размещен непосредственно для помощника Html.DropDownList:

c#
IList<Category> categories = new IList<Category>()
    {
        new Category() { ID = 1, Name = "Category 1" },
        new Category { ID = 2, Name = "Category 2" }
    };

SelectList categoryDropDown = new SelectList(categories, "ID", "Name");

ViewData["categoryDropDown"] = categoryDropDown;

затем выполните:

c#
<%=Html.DropDownList("CategoryID", ViewData("categoryDropDown"))%>

Таким образом, вы можете передавать IList категорий из любого места (уровень службы, метод контроллера).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...