MVC Templated Helper - DropDown

Using the template helpers in MVC2.0, I came across dillema how to get items to populate a drop down list. I use the attribute [UIHint(BadgesDropDown)], but how do I get list items without breaking the MVC pattern if the controller places them in ViewData? Should I BadgesDropDown.ascxcall an assistant to get them?

Right now I'm going to:

BadgesDropDown.ascx

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

controller

ViewData["Badges"] = new SelectList(SiteRepository.GetBadges(), "RowKey", "BadgeName");

Is that the way?

+3
source share
3 answers

MVC 2 introduced a new new method ... which, if used, uses all the attribute data.

<%@ 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>

2 . UIHint , . UIHint , , , . - , , .

, :

Nerd Dinner

[1]: codeclimber.net.nz -a-dropdownlist-with-asp.net-mvc [2]: bradwilson.typepad.com templates-part-5-master-page-templates

0

. , . html. ViewModels, , , , .

, , EditorTemplate.

() ViewModel, :

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));
  }
}

, , ( , ?):

public class EmailModel
{
  // Constructors

  public EmailModel()
  {
    Priority = new SelectModel("normal", _ToPrioritySelectItems());
  }

  // Properties

  public SelectModel Priority { get; set; }

  // Methods

  private IEnumerable<SelectListItem> _ToPrioritySelectItems()
  {
    List<SelectListItem> result = new List<SelectListItem>();

    result.Add(new SelectListItem() { Text = "High", Value = "high" });
    ...
  }

, . , ViewModel.

SelectModel.ascx Shared/EditorTemplates

<%@ 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>

. OptionFor - ,

, , ModelBinder . "Priority.Value". , Value , SelectModel, . , , .

, " " , " ". , MultiSelect, .

, .

, ViewModel :

public interface IValidatable
{
  bool HasValue { get; }
  bool IsValid { get; }
}

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; }
+2

I implemented the solution as shown above. It should be noted that assistants should only work with the data provided to them, see Viewing the dependency

Best practice - write HTML helpers do not know about controllers and contexts. They should do their work only on the basis of what data is provided by the caller.

I agree with the statement above. You just have to do a lot of work compared to the usual ASP.Net development.

-1
source

Source: https://habr.com/ru/post/1721391/


All Articles