Извлекать данные из представления, я должен использовать связыватель модели? - PullRequest
3 голосов
/ 01 апреля 2011

Я немного растерялся, поскольку на самом деле я не смотрел на связующие модели, поэтому, если возможно, можно ли мне посоветовать, правильно ли я думаю о своей проблеме ... :) и если мой код подходит, пожалуйста ...

1 -У меня есть класс DTO, который содержит «настраиваемые поля», каждое из которых имеет имя и другие свойства, т. Е .:

Public Class CustomFields
{
 public string Name {get;set;}
 public string Description {get;set;}
 public string FieldType {get;set;}
 public string Value {get;set;}
}

2- На уровне репо / бизнеса я устанавливаю значения и возвращаю ICollection для представления, которое будет отображаться

3 - представление использует foreach для отображения полей

<% foreach (var item in Model) {%>
   <div class="editor-label">
      <%= Html.Label(item.Name) %>
   </div>
   <div class="editor-field">
      <%= Html.TextBox(item.Name, item.Value)%>
   </div>
<% } %>

Вопрос: Как лучше всего получить результат по почте? Если есть ошибки, мне нужно отправить ошибки обратно в представление ...

ПРИМЕЧАНИЕ: что я сделал ->

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index([ModelBinder(typeof(CustomModelBinder))] ICollection<CustomFields> Fields)
{
//code here...
}

Пользовательский связыватель модели получает значения из коллекции форм и преобразует их в правильный тип - это правильно? Лучший способ сделать это? У меня такое чувство, что я слишком усложнил вещи ...

public class CustomModelBinder : IModelBinder
{
 public object BindModel(ControllerContext controllerContext, 
 ModelBindingContext    bindingContext)
 {

  var fields = new List<CustomFields>();

  var formCollection = new FormCollection(controllerContext.HttpContext.Request.Form);

  foreach (string _key in formCollection)
  {
    if (_key.Contains("_RequestVerificationToken"))
         break;

    fields.Add(new CustomFields { Name = _key, 
    Value = formCollection.GetValue(_key).AttemptedValue });
  }
  return fields;
 }
}

1 Ответ

3 голосов
/ 01 апреля 2011

Все идеально до шага 3, где вы упоминаете циклы foreach в представлении.Вот где я остановился бы и использовал шаблоны редактора.Замените цикл в вашем представлении на:

<%= Html.EditorForModel() %>

и внутри соответствующего шаблона редактора, который будет отображаться для каждого элемента коллекции моделей (~/Views/Shared/EditorTemplates/CustomFields.ascx):

<div class="editor-label">
   <%= Html.LabelFor(x => x.Name) %>
</div>
<div class="editor-field">
   <%= Html.TextBoxFor(x => x.Name) %>
</div>
<div class="editor-field">
   <%= Html.TextBoxFor(x => x.Value) %>
</div>
<div class="editor-field">
   <%= Html.TextBoxFor(x => x.Description) %>
</div>
<div class="editor-field">
   <%= Html.TextBoxFor(x => x.FieldType) %>
</div>

тогда просто:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(IEnumerable<CustomFields> fields)
{
    //code here...
}

Нет необходимости в каких-либо модельных папках.Шаблон редактора позаботится о создании собственных имен для полей ввода, чтобы они были правильно связаны.

...