Как предотвратить ошибку ModelBinder в обязательных полях списка? - PullRequest
1 голос
/ 19 октября 2010

Я получил этот объект, созданный из EntityFramework из моей базы данных.

[EdmEntityTypeAttribute(NamespaceName="ContactCoreModel", Name="TargetLang")]
[Serializable()]
[DataContractAttribute(IsReference=true)]
public partial class TargetLang : EntityObject
{
    #region Factory Method

    /// <summary>
    /// Create a new TargetLang object.
    /// </summary>
    /// <param name="idTarget">Initial value of the idTarget property.</param>
    /// <param name="idLang">Initial value of the idLang property.</param>
    /// <param name="name">Initial value of the name property.</param>
    public static TargetLang CreateLinguaTarget(global::System.Int32 idTarget, global::System.Int32 idLang, global::System.String name)
    {
        TargetLang targetLang = new TargetLang();
        targetLang.idTarget = idTarget;
        targetLang.idLang = idLang;
        targetLang.name = name;
        return targetLang;
    }

    #endregion

    [...]

    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
    [DataMemberAttribute()]
    public global::System.String name
    {
        get
        {
            return _nome;
        }
        set
        {
            OnnomeChanging(value);
            ReportPropertyChanging("name");
            _nome = StructuralObject.SetValidValue(value, false);
            ReportPropertyChanged("name");
            OnnomeChanged();
        }
    }
}

В моем представлении создания я сделаю что-то вроде

<% using (Html.BeginForm()) { %>
  <% foreach (var lang in Env.ActiveLangs) { %>
    <fieldset>
      <legend>Data for language <%: lang.name %></legend>
      <% var targetLang = Model.targetsLangs.FirstOrDefault(lt => lt.idLang.Equals(lang.id)) ?? new TargetLang(); %>
      <div class="editor-label">
        <%: Html.Hidden("targetLangs.Index", lang.id)%>
        <%: Html.Hidden("targetLangs[" + lang.id + "].idLingua", lang.id)%>
        <%: Html.Hidden("targetLangs[" + lang.id + "].idTarget", Model.id)%>
        <%= Html.Label("targetLangs_" + lang.id + "__name", "name")%>
      </div>
      <div class="editor-field">
        <%: Html.TextBox("targetLangs[" + lang.id + "].name", targetLang.name)%>
        <%: Html.ValidationMessage("targetLangs[" + lang.id + "].name")%>
      </div>
    </fieldset>
  <% } %>
  <p>
    <input type="submit" value="Create" />
  </p>
<% } %>

И в моих контроллерах

[HttpPost]
public ActionResult Create(IList<TargetLang> targetLangs)
{
  if (ModelState.IsValid)
  {
    _repTargetsLangs.Add(targetLangs);
    _repTargetsLangs.Save();

    return RedirectToAction("Index");
  }

  return View(target);
}

Проблема в том, что ModelState всегда недопустим, потому что вы можете отправить только имя для всех языков - вам не нужно переводить цель на все языки - но имя обязательно для db, поэтому модель Binder вызывает ошибка.

Мой вопрос: где мне нужно действовать, чтобы исправить эту ошибку?
На уровне связующего модели?
В контроллере перед вызовом ModelState.IsValis? И как?

Я уверен, что этот случай случился со многими, но я не могу найти элегантное, масштабируемое решение.
Спасибо.

1 Ответ

0 голосов
/ 19 октября 2010

Назовите скрытое поле, которое найдет связыватель модели:

    <%: Html.Hidden("targetLangs[" + lang.id + "].idTarget", Model.id)%>
    <%= Html.Label("targetLangs_" + lang.id + "__name", "name")%>
    <%= Html.Hidden("targetLangs_" + lang.id + "__name", "name")%>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...