我有一个视图模型,它使用valueinjector注入模型中的值(我还实现了TPT继承)。在这个过程中,由于我的一个自定义属性(不在模型源中的属性),我不断收到以下错误:
对象引用未设置为对象的实例。
我发现那个价值注入器时不时地会去那个地方。如下面的示例所示,自定义属性为"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
但是,在我的场景中这并不容易,因为我已经继承了基类和派生类中的一个类。实现自定义值注入器也是不可能的,因为您可以从EmployeeVm视图模型中看到它。
this.InjectFrom<Employee>(employee);
如果有人能帮助我实现这一点,或者有任何其他解决方案,我将不胜感激。
此外,还有观众的thanx。
试试这个:
在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。匹配用于返回源和目标属性是否匹配,useSourceProp用于忽略SourceProperty,使其不映射到目标属性。
在您的场景中,源属性没有Full-Name属性,关于匹配,您不必像名称不匹配一样判断它不会映射属性。
错误是由于
LastName.ToUpper()
它试图在分配值之前将LastName属性转换为上限。因此,如果在valueinjector设置值之后在构造函数中设置值,那么问题就应该得到解决。