作为我正在处理的网站的一部分,用户可能需要更新每个提交的故障单的部分信息。当我使用这个具有显式运算符将其转换为字符串的特定类测试TryUpdateModel
时,我得到InvalidCastException
。我已经设法将此异常从之前的所有MVC代码中分离出来:
类
public class ConversionOperator
{
public ConversionOperator()
{
FullName = string.Empty;
}
public ConversionOperator(string fullName)
{
FullName = fullName;
}
public string FullName { get; set; }
public static explicit operator string(ConversionOperator item)
{
return item == null
? string.Empty
: item.FullName;
}
public static explicit operator ConversionOperator(string item)
{
return string.IsNullOrEmpty(item)
? new ConversionOperator()
: new ConversionOperator(item);
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
ConversionOperator other = (ConversionOperator) obj;
return FullName == other.FullName;
}
}
单元测试
[TestMethod]
public void Verify_Conversion_To_String()
{
ConversionOperator first;
first = new ConversionOperator("Henry Beauford Autumnbottom Elderberry McClatchen");
Assert.AreEqual(first.FullName, (string) first); // passes
Assert.IsTrue(first.Equals("Henry Beauford Autumnbottom Elderberry McClatchen")); // throws exception
}
[TestMethod]
public void Verify_Conversion_From_String()
{
string name = "Henry Beauford Autumnbottom Elderberry McClatchen";
Assert.AreEqual((ConversionOperator) name, new ConversionOperator(name));
}
Verify_Conversion_To_String
中的第一个断言传递,但第二个失败,抛出InvalidCastException
。很明显,.NET Framework知道obj
是string
,但是没有调用显式转换。
从强制转换为as ConversionOperator
会产生一个空对象,也不正确。
答案 0 :(得分:1)
看起来您正在将String
传递给您的Equals方法。如果是这种情况,那么它将使投射失败到ProperName
。
您可以做的是创建一个不同的Equals方法,该方法接受一个字符串(或多个字符串)并针对ProperName
属性测试这些字符串,看看它们是否匹配:< / p>
public bool Equals(string fullName, t1 middleNameOptions, t2 displayOptions)
{
return this.FullName == item.FullName
&& this.MiddleNameOptions == item.MiddleNameOptions
&& this.DisplayOptions == item.DisplayOptions;
}
答案 1 :(得分:1)
我通过实施IEquatable<string>
:
public bool Equals(string other)
{
ConversionOperator item = new ConversionOperator(other);
return this.Equals(item);
}
现在单元测试通过了,我将在墙上敲我的头直到忘记我问这个问题。
答案 2 :(得分:0)
为防止发生异常,您可以调用对象的ToString()
方法:
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
ProperName item = (ConversionOperator) obj.ToString();
return FullName == item.FullName
&& MiddleNameOptions == item.MiddleNameOptions
&& DisplayOptions == item.DisplayOptions;
}
为了让TryUpdateModel方法将模型绑定到给定的前缀(表单数据),您可能需要隐式转换。
如果你看一下the source for the Controller class,可以看一下,DefaultModelBinder
被使用了。
DefaultModelBinder
有局限性,对于专门的模型通常更好,然后将其映射到您的域模型(可能使用手动编写的代码,或使用AutoMapper)
如果你无法改变你的方法,那么我建议创建一个Custom Model Binder,它可以直接控制表格如何被转换为模型。