Class中的显式强制转换字符串失败

时间:2014-01-13 23:33:17

标签: c# asp.net-mvc

作为我正在处理的网站的一部分,用户可能需要更新每个提交的故障单的部分信息。当我使用这个具有显式运算符将其转换为字符串的特定类测试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知道objstring,但是没有调用显式转换。

从强制转换为as ConversionOperator会产生一个空对象,也不正确。

3 个答案:

答案 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,它可以直接控制表格如何被转换为模型。