2

我有一个视图模型,它使用 valueinjector 从模型中注入值(我还实现了 TPT 继承)。在此过程中,由于我的一个自定义属性(不在模型源中的属性),我不断收到以下错误:

你调用的对象是空的。

我发现 valueinjector 时不时地继续访问该属性。如以下示例所示,自定义属性为“FullName”。

public class EmployeeVm
{
    public EmployeeVm(Employee employee)
    {
        this.InjectFrom<Employee>(employee);
    }

    public EmployeeVm(int id):this(new Context().Employees.Find(id))
    {
    }

    public EmployeeVm()
    {
    }
    public int EmployeeId { get; set; }
    [Display(Name = "First Name")]
    [Required(ErrorMessage = "Pleae enter First Name"), StringLength(50)]
    public string FirstName { get; set; }
    [Display(Name="Middle Name"), StringLength(50)]
    public string MiddleName { get; set; }
    [Display(Name="Last Name"), StringLength(50)]
    [Required(ErrorMessage = "Please enter Last Name")]
    public string LastName { get; set; }

    public string FullName {
        get
        {
            StringBuilder stringBuilder = new StringBuilder();

            stringBuilder.Append("<b>");
            stringBuilder.Append(LastName.ToUpper());
            stringBuilder.Append("</b>");
            if (!string.IsNullOrEmpty(MiddleName))
            {
                stringBuilder.Append(", ");
                stringBuilder.Append(MiddleName);
            }
            stringBuilder.Append(", ");
            stringBuilder.Append(LastName);

            return stringBuilder.ToString();
        }
    }        
}

我想到的唯一解决方案是让 valueinjector 忽略该属性,这样它就不会在设置其他属性之前尝试获取该属性。为此,我尝试在员工模型中编写自定义注入器,如下所示:

[Table("Person")]
public abstract class Person:ConventionInjection
{
    public Person()
    {
        this.PersonAddresses = new List<PersonAddress>();
        this.PersonEmails = new List<PersonEmail>();
        this.PersonPhones = new List<PersonPhone>();
    }

    [Key]
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }



    //public virtual Employee Employee { get; set; }

    protected override bool Match(ConventionInfo c)
    {
      throw new NotImplementedException();
    }



    public List<PersonAddress> PersonAddresses { get; set; }
    public List<PersonEmail> PersonEmails { get; set; }
    public List<PersonPhone> PersonPhones { get; set; }
}

public class Employee:Person
{
    public Employee()
    {
        this.Identifications=new List<Identification>();
        this.BankAccounts=new List<BankAccount>();
    }
    public DateTime? DateOfBirth { get; set; }
    //Other properties are inherited from Person abstract class

    public virtual ICollection<Identification> Identifications { get; set; }
    public virtual ICollection<BankAccount> BankAccounts { get; set; }

    protected override bool Match(ConventionInfo c)
    {
        if (c.TargetProp.Name == "FullName")
        {
            return false;
        }



        var isMatch = (c.SourceProp.Name == "PersonId" && c.TargetProp.Name == "EmployeeId") ||
                      (c.SourceProp.Name == c.TargetProp.Name && c.SourceProp.Type == c.TargetProp.Type);

        return isMatch;

    }
}

尽管如此,我仍然遇到上述相同的错误。

我还找到了另一个解决方案,它说要覆盖 LoopValueInjection 的 UseSourceProp 方法。

http://valueinjecter.codeplex.com/discussions/234706

但是,在我的场景中它并不那么容易,因为我已经在我的基类和派生类中继承了一个类。并且实现自定义 valueinjector 也是不可能的,因为您可以从 EmployeeVm 视图模型中看到它。

this.InjectFrom<Employee>(employee);

如果有人可以帮助我进行此实施或是否有任何其他解决方案,我将不胜感激。

另外,感谢观众。

4

1 回答 1

3

尝试这个:

在 EmployeeVm 的构造函数中:

public EmployeeVm(Employee employee)
{
    this.InjectFrom<Employee>(employee);

    stringBuilder = new StringBuilder();
    stringBuilder.Append("<b>");
    stringBuilder.Append(LastName.ToUpper());
     stringBuilder.Append("</b>");
     if (!string.IsNullOrEmpty(MiddleName))
     {
           stringBuilder.Append(", ");
           stringBuilder.Append(MiddleName);
     }
      stringBuilder.Append(", ");
     stringBuilder.Append(FirstName);
     this.FullName = stringBuilder.ToString();
}

将 FullName 属性转换为 auto 属性:

public string FullName { get; set; }

此外,将 Employee 中的覆盖方法更改为:

protected override bool Match(ConventionInfo c)
{
    var isMatch = (c.SourceProp.Name == "PersonId" && c.TargetProp.Name == "EmployeeId") ||(c.SourceProp.Name == c.TargetProp.Name && c.SourceProp.Type == c.TargetProp.Type);

      return isMatch;

}

您不需要覆盖 LoopValueInjector 的 match 属性或 useSourceProp。match 用于返回源和目标属性是否匹配,而 useSourceProp 用于忽略 SourceProperty,使其不映射到目标属性。

在您的方案中,源属性没有 Full Name 属性,并且关于匹配您不必告诉它是否名称不匹配它不会映射该属性。

错误是由于

LastName.ToUpper()

在分配值之前,它试图将 LastName 属性转换为上层。所以,如果在valueinjector设置值之后在构造函数中设置值,问题应该就解决了。

于 2013-12-17T03:52:49.017 回答