如何防止列表的必填字段中出现 ModelBinder 错误?

发布于 2024-09-27 18:59:10 字数 3169 浏览 5 评论 0原文

我已经从数据库中的 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 始终无效,因为您只能提交所有语言的名称 - 您不必翻译所有语言的目标 - 但name 对于 db 是必需的,因此模型 Binder 会引发错误。

我的问题是:我必须在哪里操作才能纠正此错误?
在模型绑定器级别?
在 ModelState.IsValis 调用之前的 Controller 中? 又如何呢?

我相信很多人都遇到过这种情况,但我找不到一个优雅的、可扩展的解决方案。
谢谢。

I've got this object created from EntityFramework from my database.

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

In my Create View I'll do something like

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

And in my Controllers

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

    return RedirectToAction("Index");
  }

  return View(target);
}

The problem is that ModelState is always invalid, because you can submit only a name for all the languages - you haven't to translate the target in all languages -, but the name is mandatory for db, so the model Binder raises an error.

My question is: where I have to operate, to correct this error?
At the Model binder level?
In the Controller before the ModelState.IsValis call?
And how?

I'm sure this case has happened to many, but I can't find an elegant, scalable solution.
Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小猫一只 2024-10-04 18:59:10

将 name 设为模型绑定器将找到的隐藏字段:

    <%: Html.Hidden("targetLangs[" + lang.id + "].idTarget", Model.id)%>
    <%= Html.Label("targetLangs_" + lang.id + "__name", "name")%>
    <%= Html.Hidden("targetLangs_" + lang.id + "__name", "name")%>

Make name a hidden field that the model binder will find:

    <%: Html.Hidden("targetLangs[" + lang.id + "].idTarget", Model.id)%>
    <%= Html.Label("targetLangs_" + lang.id + "__name", "name")%>
    <%= Html.Hidden("targetLangs_" + lang.id + "__name", "name")%>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文