Catel:我怎么知道SavableModelBase.Load何时失败?

时间:2017-05-23 19:28:11

标签: c# mvvm catel

使用Catel 4.4.0。

我让用户使用Load(流,XML模式)方法浏览并加载他的数据文件,该数据文件是来自SavableModelBase子类实例(模型ABC)的数据。这个用户犯了一个错误并加载了错误的文件,这个文件也是一个SavableModelBase子类,但却是一个完全不同的模型(模型XYZ)。代码经历了反序列化数据的动作,但当然,没有找到模型ABC的属性,因此返回的实例(模型ABC)仅包含属性的默认值。

我希望Load方法返回null值或引发异常。如何确定加载一个全新的模型ABC实例并因此确实具有默认属性值,并意外地尝试将模型XYZ加载为模型ABC之间的区别?我没有看到SavableModelBase的任何属性会提醒我可能的混淆。

SaveableModelBase内置了哪些内容可以帮助我确定加载错误,还是需要提出某种解决方法?

如果您需要更多信息,请告诉我们。谢谢!

好色

2 个答案:

答案 0 :(得分:0)

由于类可以(de)序列化多种格式(即使改变了xml结构),也没有真正的方法来查看这是否失败。在这种情况下,我会检查所需的属性和/或为要以不同方式加载的每种类型使用不同的文件类型扩展名。

答案 1 :(得分:0)

我决定使用自己的Load方法创建一个SavableModelBase的子类。此Load方法将首先读取文件的根节点,该节点的名称与保存文件的类的名称相同。如果它们比较OK,则继续使用父SavableModelBase类Load方法加载。否则,抛出异常。 (而且我现在忽略了使用二进制模式加载。)

public class LexSavableModelBase<T> : SavableModelBase<T> where T : class
{
    // SNIP!

    public static new T Load(Stream stream, SerializationMode mode)
    {
        Argument.IsNotNull(() => stream);

        if (mode == SerializationMode.Xml)
        {
            using (XmlReader xr = XmlReader.Create(stream))
            {
                xr.MoveToContent();
                string rootName = xr.LocalName;
                if (string.Compare(rootName, typeof(T).Name, StringComparison.OrdinalIgnoreCase) != 0)
                {
                    throw new InvalidDataException(string.Format(CultureInfo.CurrentCulture, "Expecting data from Model [{0}], but found Model [{1}] instead.", typeof(T).Name, rootName));
                }

                // Reset to read from the top.
                stream.Seek(0, SeekOrigin.Begin);
            }
        }

        return SavableModelBase<T>.Load<T>(stream, mode);
    }
}

我确信必须两次读取部分文件才会有性能损失而且我只是做了足够的事情来满足我的一小部分场景,但它似乎做了我需要它 - 检测何时正在提供错误的数据以进行加载。我只在我应用程序中的150多个模型中使用它。这些是客户保存到磁盘上的文件并从中加载的文件。

如果你可以做任何改进,请做。如果您有任何问题,请告诉我。