模型绑定不匹配值

时间:2016-03-05 18:46:45

标签: c# asp.net-mvc-4 razor

我遇到了一个问题,我似乎无法在这里弄清楚,而且我已经做了相当多的搜索:

在我的模型(对象列表)中,我有以下输出:

<input data-val="true" data-val-number="Please enter a number." data-val-required="The ModelID field is required." id="Students_19__ModelID" name="Students[19].ModelID" type="hidden" value="62">

如果你仔细观察这个值是62(我已经绑定了第二个对象只是为了检查自己,我发现它也是62:

<input data-val="true" data-val-number="Please enter a number." id="Students_19__storage_ID" name="Students[19].storage.ID" type="hidden" value="62">

在同一视图中,我看到了这一点:

@Html.LabelFor(_ => Model.Students[i].Show, "ID: " + Model.Students[i].storage.ID)

制备:     ID:63

总结:

@Html.HiddenFor(_ => Model.Students[i].storage.ID)
@Html.LabelFor(_ => Model.Students[i].Show, "ID: " + Model.Students[i].storage.ID)

OR

@Html.HiddenFor(m => m.Students[i].storage.ID)
@Html.LabelFor(m => m.Students[i].Show, "ID: " + Model.Students[i].storage.ID)

produces-&GT;

<input data-val="true" data-val-number="Please enter a number." id="Students_19__storage_ID" name="Students[19].storage.ID" type="hidden" value="62">
<label for="Students_19__Show">ID: 63</label>

显然62!= 63这就是在控制器中抛弃模型。有没有人知道可能导致这种情况的原因?我觉得某些事情正在变得很糟糕,但我现在已经没有想法了。我之前已经看到过这种行为并且在隐藏字段的加载顺序周围移动已经修复了它,但这显然不是一个好的解决方案。

编辑:每条评论:   对象的结构非常温顺:(这是“存储”变量)

public class EducationGoalModel
  {
    public int? ID { get; set; }
    public decimal Amount { get; set; }
    public string Name { get; set; }
    public string Category { get; set; }

    //Education
    public int StudentAge { get; set; }
    public int StudentBegin { get; set; }
    public int StudentYears { get; set; }

    [DisplayFormat(DataFormatString = "{0:P2}", ApplyFormatInEditMode = true)]
    [Percentage] //Custom annotation, nothing silly here
    [Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(Resources.Errors))] //Error is not triggered otherwise the ID wouldn't work in the "workaround"
    public decimal Inflation { get; set; }

    // This is just used by another module that needs annotations waaaay down the line, these values are unused.
    public decimal TargetAmount { get { return Calculations.FutureValue(this.YearOfCompletion - DateTime.Now.Year, this.Inflation, this.Amount); } } 
    public byte RiskToleranceLevel { get; private set; }
    public int YearOfCompletion { get; set; }
    public bool Hide { get; set; }

    public EducationGoalModel()
    {
      this.Category = FinanceGoalTargetCategory.EDUCATIONAL;
    }

    public EducationGoalModel(EducationGoal goal) 
    {
      //The goal is just the entity I'm using, this is a light wrapper around it.
      ID = goal.ID;
      Amount = goal.Amount;
      Name = goal.Name;
      Category = goal.Category;
      StudentAge = goal.StudentAge;
      StudentBegin = goal.StudentBegin;
      StudentYears = goal.StudentYears;
      Inflation = goal.Inflation;
      Hide = goal.Hide;
    }

    public void CopyTo(EducationGoal goal)
    { //SNIP.... we don't really care about this method, it isn't called
  }

这是视图模型:

  public class EducationGoalInputModel : InputModelBase
  {
        public CurrencySliderModel AmountSlider { get; set; }
        public EducationGoalModel storage { get; set; }
        public int ModelID { get; set; }
        public int StudentAge { get; set; }
        public int StudentBegin { get; set; }
        public int StudentYears { get; set; }
        [MaxLength(20, ErrorMessageResourceName = "FinancialGoalsNameLength", ErrorMessageResourceType = typeof(Resources.Errors))]
        public string Name { get; set; }
        [DisplayFormat(DataFormatString = "{0:P2}", ApplyFormatInEditMode = true)]
        [Percentage]
        [Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(Resources.Errors))]
        public decimal Inflation { get; set; }
  ... plain constructor (no args), a second to construct and establish the "storage" object which is the one used for the above output.

这是基类,真的没什么有趣的:

public abstract class InputModelBase { //a simple class that has 
  public abstract void UpdateAmounts(int age);
  //and a couple other utility methods for the user interface (we support IE8 so a lot of UI information is stored)
}

编辑:Per Hacks: 因为这是MVC(这种方法很好,但维护很糟糕并且表明问题更严重)

<input type="hidden" name="@String.Format("Students[{0}].storage.ID", i)" id="@String.Format("Students_{0}__storage_ID", i)" value="@Model.Students[i].storage.ID" />

使用上面的示例输出value="63"的正确值。

编辑#2 根据以下评论的反馈 *(谢谢!),看起来ModelState与模型不一致。没有什么能明显修改View 中的ModelState,我可以找到,但我继承了这个项目,并且可能有一些扩展方法正在做我需要追踪的事情。此特定测试中的值5. ModelState显示错误的值,因此绑定错误。这并没有解决问题,但基本上是一个公认的答案,因为我现在知道在哪里看。

感谢您的帮助。

0 个答案:

没有答案