Templates MVC模板辅助程序-下拉列表

Templates MVC模板辅助程序-下拉列表,templates,asp.net-mvc-2,drop-down-menu,Templates,Asp.net Mvc 2,Drop Down Menu,使用MVC2.0中的模板化助手,我遇到了一个难题,即如何获取项目以填充dropdownlist。 我使用的是[UIHint(BadgesDropDown)]属性,但是如果控制器将列表项放在ViewData中,我将如何在不违反MVC模式的情况下获取列表项?BadgesDropDown.ascx是否应该调用帮助程序来获取它们 现在我要做的是: BadgesDropDown.ascx <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewU

使用MVC2.0中的模板化助手,我遇到了一个难题,即如何获取项目以填充dropdownlist。 我使用的是
[UIHint(BadgesDropDown)]
属性,但是如果控制器将列表项放在ViewData中,我将如何在不违反MVC模式的情况下获取列表项?
BadgesDropDown.ascx
是否应该调用帮助程序来获取它们

现在我要做的是:

BadgesDropDown.ascx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%= Html.DropDownList("", ViewData["Badges"] as IEnumerable<SelectListItem>)%>

这就是解决方法吗?

我实现了上述示例中的解决方案。需要注意的一点是,助手应该只处理提供给他们的数据,请参阅

最佳实践是编写Html 帮助程序不知道控制器和 上下文。他们应该做好自己的工作 仅基于供应商提供的数据 打电话的人


我同意上述说法。只是与常规的ASP.Net开发相比,需要做大量的工作。

在MVC2中,一个伟大的新方法。。。如果使用,则依赖于所有属性数据

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
Inherits="System.Web.Mvc.ViewPage<glossaryDB.EntityClasses.AssociationEntity>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Association: Edit
</asp:Content>

<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server">
    <h3>Association: Edit</h3>
    <% using (Html.BeginForm()) { %>
        <fieldset style="padding: 1em; margin: 0; border: solid 1px #999;">
            <%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>
            <%= Html.EditorForModel() %>
            <input type="submit" value="  Submit  " />
        </fieldset>
    <% } %>
    <p><%= Html.ActionLink("Details", "Index") %></p>
</asp:Content>

协会:编辑
协会:编辑

要使其工作,有两个选项。UIHint必须提供数据源,或者控制器必须提供数据源。如果UIHint没有,则提供给下拉列表的数据是固定的。另一个选项是控制器,它允许我们根据需要使用不同的数据集切换下拉数据

我发现了一些相关的例子:

书呆子晚餐

[1] :searcch for codeclimber.net.nz和how-to-create-a-dropdownlist-with-asp.net-mvc
[2] :bradwilson.typepad.com和templates-part-5-master-page-templates

最近关于这个话题有很多讨论。在日期、日期范围和多选复选框列表中也会遇到类似的障碍。您可能希望在任何地方使用一组丰富的html控件。我一直在试验子视图模型的概念,我认为解决方案比我尝试过的其他方法更简洁

基本概念是定义一个与自定义EditorTemplate紧密耦合的小视图模型

在您的示例中,我们将从特定于单个选择列表的(子)视图模型开始:

public class SelectModel
{
  #region SelectModel(string value, IEnumerable<SelectListItem> items)
  public SelectModel(string value, IEnumerable<SelectListItem> items)
  {
    _value = value;
    Items = new List<SelectListItem>(items);

    _Select();
  } 
  #endregion

  // Properties

  public List<SelectListItem> Items { get; private set; }

  public string Value
  { 
    get { return _value; }
    set { _value = value; _Select();}
  }
  private string _value;

  // Methods

  private void _Select()
  {
    Items.ForEach(x => x.Selected = (Value != null && x.Value == Value));
  }
}
然后,我有一个自定义ValidationAttribute:

public class IsValidAttribute : ValidationAttribute
{
  // Constructors

  public IsValidAttribute()
  {
    ErrorMessage = "(not valid)";
  }

  // Properties

  public bool IsRequired { get; set; }

  // Methods

  private bool Is(object value)
  {
    return value != null && !"".Equals(value);
  }

  public override bool IsValid(object value)
  {
    if (!Is(value) && !IsRequired)
      return true;

    if (!(value is IValidatable))
      throw new InvalidOperationException("IsValidAttribute requires underlying property to implement IValidatable");

    IValidatable validatable = value as IValidatable;
    return validatable.IsValid;
  }
}
现在,您可以将属性放置在基于子ViewModel的属性上,就像任何标量属性一样:

[IsValid(ErrorMessage = "Please enter a valid start date/time")]
public DateAndTimeModel Start { get; set; }
<%@ Control Inherits="System.Web.Mvc.ViewUserControl<SelectModel>" %>

<div class="set">
  <%= Html.LabelFor(model => model) %>
  <select id="<%= ViewData.ModelMetadata.PropertyName %>_Value" name="<%=ViewData.ModelMetadata.PropertyName %>.Value">
  <% foreach (var item in Model.Items) { %>
    <%= Html.OptionFor(item) %>
  <% } %>
  </select>
</div>
public interface IValidatable
{
  bool HasValue { get; }
  bool IsValid { get; }
}
public class IsValidAttribute : ValidationAttribute
{
  // Constructors

  public IsValidAttribute()
  {
    ErrorMessage = "(not valid)";
  }

  // Properties

  public bool IsRequired { get; set; }

  // Methods

  private bool Is(object value)
  {
    return value != null && !"".Equals(value);
  }

  public override bool IsValid(object value)
  {
    if (!Is(value) && !IsRequired)
      return true;

    if (!(value is IValidatable))
      throw new InvalidOperationException("IsValidAttribute requires underlying property to implement IValidatable");

    IValidatable validatable = value as IValidatable;
    return validatable.IsValid;
  }
}
[IsValid(ErrorMessage = "Please enter a valid start date/time")]
public DateAndTimeModel Start { get; set; }