【问题标题】:ASP.NET MVC 3 DataBinder.Eval on Viewmodel object throws "does not contain property"Viewmodel 对象上的 ASP.NET MVC 3 DataBinder.Eval 抛出“不包含属性”
【发布时间】:2012-10-05 19:27:04
【问题描述】:

我有一个使用标准模型的视图,但现在我需要在页面上添加来自两个不同模型的信息。在做了一些研究来处理这个问题后,我创建了一个 ViewModel。现在我在尝试显示我的观点时遇到错误:

DataBinding:“VirtualAuthtech.ViewModels.CMSCalculatorViewModel”不包含名为“WORKCY”的属性。

这是我的视图模型

namespace VirtualAuthtech.ViewModels
{
    public class CMSCalculatorViewModel
    {
        public CPT CPT { get; set; }
        public GPCI GPCI { get; set; }
    }
}

CPT 是我最初使用的第一个模型,然后我需要添加 GPCI

这是我的视图的 ActionResult

public ActionResult _CMSCalculator()
        {
            string CPTCode = string.Empty;
            string MOD = string.Empty;
            string GPCIPayID = "31146";
            string GPCIYear = "2011";
            if (Request.Params["CPT1"] != null)
            {
                CPTCode = Request.Params["CPT1"];
                MOD = Request.Params["MOD"];
            }
            return PartialView("_CMSCalculatorPanel", (string.IsNullOrEmpty(CPTCode) ? null as CMSCalculatorViewModel : CPTDataHelper.GetCPTGPCI(CPTCode, MOD, GPCIPayID, GPCIYear)));
        }

这是从我的模型中获取数据的方法

    public static CMSCalculatorViewModel GetCPTGPCI(string CPTCode, string MOD, string GPCIPayID, string GPCIYear)
    {
        using (var DB = new VADataContext())
        {
            var view = new CMSCalculatorViewModel();
            if (String.IsNullOrWhiteSpace(MOD))
            {
                view.CPT = (from cpt in DB.CPTs
                            where cpt.CPT1 == CPTCode
                            select cpt).FirstOrDefault<CPT>();
                view.GPCI = (from gpci in DB.GPCIs
                             where gpci.PAYID == GPCIPayID && gpci.YEAR == GPCIYear
                             select gpci).FirstOrDefault<GPCI>();
            }
            else
            {
                view.CPT = (from cpt in DB.CPTs
                            where cpt.CPT1 == CPTCode && cpt.MOD == MOD
                            select cpt).FirstOrDefault<CPT>();
                view.GPCI = (from gpci in DB.GPCIs
                             where gpci.PAYID == GPCIPayID && gpci.YEAR == GPCIYear
                             select gpci).FirstOrDefault<GPCI>();
            }
            return view;
        }
    }

现在我的视图正在使用新的 ViewModel,我正在尝试显示一个字段:

<div style='float:left; width: 35px; margin: 0; padding: 0; text-align: center; color: #094ab2'>@VirtualAuthtech.CallbackPanelHelper.GetFieldNumber(Model, "WORKCY")</div>

我在这段代码中遇到了一个错误:

public static double GetFieldNumber(object data, string fieldName)
        {
            object text = DataBinder.Eval(data, fieldName);
            if (text == null || text.ToString() == string.Empty)
                return 0;
            double number = Convert.ToDouble(text);
            return number;
        }

这是说我的模型不包含我正在寻找的字段的属性。我需要告诉它查看我的视图模型的 CPT 部分吗?

这是我创建的第一个 ViewModel,所以我可能会搞错这一切。任何帮助我朝着正确的方向前进将不胜感激!

【问题讨论】:

  • 我会说这个错误是准确的。您的模型(CMSCalculatorViewModel)包含两个属性,CPT 和 GPCI,它们都没有命名为“WORKCY”。
  • WORKCY 是 CPT 模型的一个属性,我需要进行哪些更改才能使其意识到这一点?

标签: asp.net asp.net-mvc asp.net-mvc-3 viewmodel databinder


【解决方案1】:

为什么要调用 GetFieldNumber?以下行有什么问题:

<div style='float:left; width: 35px; margin: 0; padding: 0; text-align: center; color: #094ab2'>@Model.CPT.WORKCY</div>

但如果你必须使用运行时绑定,那么你的函数中的行可能应该是:

object text = DataBinder.Eval((CMSCalculatorViewModel)data.CPT, fieldName);

【讨论】:

  • 我不能这样做,因为它一开始就是一个空模型。当用户根据他的选择从网格中选择一个项目时,该字段会更新。还有更多的领域也有其背后的逻辑。
  • 我更新了代码,但是对象是否为 NULL 开始并不重要...只要它是强类型的,您就可以在设计时直接引用字段而不是运行时。
  • 我试过你的代码,它说我不能对空引用进行运行时数据绑定。我将发布一个可行的解决方案,但如果您得到一个不涉及确保我的模型对于每个字段都不为空的解决方案,请告诉我。
  • 您更新代码的问题是我将不得不创建一组新方法,因为我的原始方法用于具有不同模型的其他页面。如果我告诉它使用 data.CPT 那么它将不再在任何其他页面上工作。感谢您对此的帮助。
  • 请记住,在 MVC(设计模式)中,您的 View 应该知道并专门为 Model(或本例中为 VieWModel)指定,因此除非有特定的后期绑定原因,否则您应该能够在设计时完成所有这些工作并完全避免使用 Eval。
【解决方案2】:

我能够使用此代码使其正常工作。

<div style='float:left; width: 35px; margin: 0; padding: 0; text-align: center; color: #094ab2'>@if(Model == null) { <text>0</text> } else { @VirtualAuthtech.CallbackPanelHelper.GetFieldNumber(Model.CPT, "WORKCY") }</div>

但是,我在此视图中还有很多其他字段。我宁愿不必检查每个模型是否为空。如果您有其他解决方案,请分享。

【讨论】:

  • 看起来不错,但是你为什么不直接将你的模型设置为一个新的、空白的、空的模型,然后你就不必进行后期绑定了?
  • 我继续初始化模型以使用列表中无论如何都会选择的第一项,因此它不会以 null 开始。现在它可以在没有数据绑定的情况下工作。这似乎是一种更清洁的方法。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-29
  • 1970-01-01
相关资源
最近更新 更多