在 Windows Phone SharePoint 应用中实现业务逻辑和数据验证

在使用 Windows Phone SharePoint 列表应用模板创建的 Windows Phone 应用中实现数据验证。

在用于生产的 Windows Phone 应用程序中,您可能需要验证用户输入的数据,这样做的目的在于强制执行与您特定的情况相关的业务逻辑,或确保数值以适当格式输入,或仅仅为了在将数值保存到 SharePoint 列表前找到错误。 基于 Windows Phone SharePoint 列表应用程序模板的项目包括默认数据验证逻辑,但这类项目也为开发人员提供实现自定义数据验证的机制。

重要

如果要开发适用于 Windows Phone 8 的应用,则必须使用 Visual Studio Express 2012 而不是 Visual Studio 2010 Express。 除开发环境外,本文中的其他所有信息都适用于创建 Windows Phone 8 和 Windows Phone 7 版应用。 > 有关详细信息,请参阅 如何:设置用于开发 SharePoint 移动应用的环境

默认数据验证规则

默认情况下,SharePoint 列表中字段的某些数据类型与简单格式或数据验证相关联。 如果您在 SharePoint 列表中为基于超链接或图片字段类型的字段输入了无效的 URL 并尝试保存您的更改,您会看到一条显示您输入的地址无效的消息。 如果您为基于日期和时间字段类型的字段输入了一个客户的名称作为字段值,您会收到一条消息,指导您为字段输入有效的日期范围。

注意

日期输入验证针对 SharePoint 的日期格式。 如果您对电话区域设置日期格式有要求,请自定义字段并添加相应验证。

默认情况下,在从 Windows Phone SharePoint 列表应用程序模板创建的 Windows Phone 应用中,也会强制实施其中一些基本验证规则。 如果在基于 SharePoint 列表的Windows Phone应用程序的“编辑”窗体中绑定到“日期和时间”类型的 SharePoint 字段的字段中输入日期值以外的任何内容,则当焦点从TextBox与字段关联的控件移开时,会看到一条验证错误消息。 (见图 1.)

图 1. Windows Phone 应用程序中的验证错误提示

Windows Phone 应用程序中的验证错误提示

编辑表单中标记为“开始时间”的文本框绑定到 SharePoint 列表中的某一日期和时间字段,此示例应用程序是以该 SharePoint 列表为基础。 如果文本框中输入了无效日期 (并且文本框随后失去焦点) ,则 (红色文本) 显示验证错误提示,因为在 ValidatesOnNotifyDataErrorsEditForm.xaml 文件中定义 的 XAML 声明中,TextBox与 控件的 属性TextBox关联的 Text 对象的属性Binding设置为 True

<StackPanel Orientation="Vertical" Margin="0,5,0,5">
   <TextBlock TextWrapping="Wrap"
              HorizontalAlignment="Left"
              Style="{StaticResource PhoneTextNormalStyle}">Start Time*
   </TextBlock>
   <TextBox Height="Auto"
            Style="{StaticResource TextValidationTemplate}"
            FontSize="{StaticResource PhoneFontSizeNormal}"
            Width="470"
            HorizontalAlignment="Left"
            Name="txtEventDate"
            Text="{Binding [EventDate], Mode=TwoWay, ValidatesOnNotifyDataErrors=True,
                       NotifyOnValidationError=True}"
            TextWrapping="Wrap" />
   <TextBlock FontSize="16"
              TextWrapping="Wrap"
              HorizontalAlignment="Left"
              Style="{StaticResource PhoneTextSubtleStyle}"
              Text="{Binding DateTimeFormat}" />
</StackPanel>

(如果 属性 ValidatesOnNotifyDataErrors 设置为 False,则在选择“ 保存 ”按钮之前,用户不会指示输入的数据无效。此时,用户会看到有关验证错误的错误消息,因为输入的日期值的格式验证仍由派生类 EditItemViewModel 的基类执行。)

但是 Windows Phone 应用程序中的某些字段可能不会给出任何数据无效的通知。 精心设计 Visual Studio 项目模板必须为通用模板以便用作许多不同应用程序的起始点。 Windows Phone SharePoint 列表应用程序模板不能包括有关具体情况的验证规则,但仍然保留其作为通用模板的值。 根据您的需要和您特定的 Windows Phone 应用程序的使用环境,您可能会想要实现您自己的自定义数据验证规则。

实现自定义的数据验证规则

可以通过多种方式验证Windows Phone应用的用户输入的数据。 使用 Windows Phone SharePoint 列表应用程序模板创建的项目包括充当窗体 (中间的类,即Windows Phone应用程序中数据的视图) (例如 EditForm.xaml 文件) 以及应用程序所基于的 SharePoint 列表中的数据本身。 可以将这些类视为 Model-View-ViewModel 设计模式的 ViewModel 组件的实现 (图 2) 。 (有关Windows Phone SharePoint 列表应用程序模板如何符合 MVVM 软件设计模式的详细信息,请参阅Windows Phone SharePoint 列表应用程序模板的体系结构。)

注意

SharePoint 列表模板不包含默认验证(例如 SharePoint 任务列表中的完成百分比、工作组讨论列表的后检查以及 SP 十进制字段类型验证),但您可以执行此类验证。

图 2. ViewModel 组件中的模板文件

ViewModel 组件中的模板文件

在基于 MVVM 模式设计的应用程序中,数据验证通常在数据层(也就是在模型组件中)处理。 在 Windows Phone SharePoint 列表应用程序模板创建的项目中,为使开发人员更容易管理数据验证,已将一个可扩展的数据验证机制“推送”一个层,并在 ViewModel 组件中得到实现。 因此,在基于该模板的项目中,存储验证用户输入或管理数据的自定义代码最合适的地点是这些 ViewModel 类。 在数据验证方面, EditItemViewModel 类和 NewItemViewModel 类 (与最有可能涉及编辑和更新列表数据的表单关联的类) 都提供了一 Validate() 个名为) 的验证方法 (的开放实现,该方法替代从中派生这两个类的类中的基验证方法。

public override void Validate(string fieldName, object value)
{
  base.Validate(fieldName, value);
}

此方法为开发人员提供一种方便的机制,使他们能在个别字段中添加自定义验证逻辑。 常规方法是检查传递给 方法的参数 fieldName 的值, Validate() 以标识要与自定义验证代码关联的字段。 例如,可以在此方法的实现中使用 语句 switch 来提供特定于 Windows 应用的“编辑”窗体 (EditForm.xaml) 中各种字段的验证逻辑。

对于以下代码示例,假定 SharePoint Server 的安装已具备自定义列表模板创建的产品订单列表。 已创建的列表中的列和字段类型如表 1 所示。

表 1. 产品订单列表

Column 类型 必需
产品(例如标题) 单行文本(文本)
说明 单行文本(文本)
数量 数字
订单日期 日期和时间 (Datetime)
完成时间 日期和时间 (Datetime)
联系人电话 单行文本(文本)

另外,出于示例目的,本示例还假定根据虚构的 Contoso, Ltd. 的业务逻辑,对给定产品订购系统强制执行简单的验证规则:

  • 履行订单的日期必须晚于下订单的日期。
  • 如果客户想要订购名为 Fuzzy Dice 的产品,则必须成对订购骰子。 根据 Contoso, Ltd.的特殊规则,根本就不存在模糊模具。
  • 在产品订单列表中,电话号码的字段类型是"单行文本:(即文本),它可以是任何文本(默认最多为 255 个字符)。 针对此示例,将强制执行格式有效性规则,要求输入的数据必须是常见电话号码格式的其中一种,例如“(555) 555-5555”。

实现自定义的验证规则

  1. 假设你已基于包含表 1 中指定的列和类型的自定义列表模板创建了 SharePoint 列表,请按照如何:创建Windows Phone SharePoint 列表应用中详述的步骤,在 Visual Studio 中使用 Windows Phone SharePoint 列表应用程序模板创建Windows Phone应用程序

  2. 解决方案资源管理器 项目的 ViewModels 文件夹中,双击 EditItemViewModel.cs 文件 (或选择该文件,然后按 F7) 打开文件进行编辑。

  3. 将以下 using 指令添加到文件顶部的指令列表中。

    using System.Globalization;
    using System.Text.RegularExpressions;
    
  4. 将 文件中 方法的默认实现 Validate() 替换为以下代码。

    public override void Validate(string fieldName, object value)
    {
        string fieldValue = value.ToString();
        if (!string.IsNullOrEmpty(fieldValue)) //Allowing for blank fields.
        {
            bool isProperValue = false;
    
            switch (fieldName)
            {
                case "Quantity":
                    // Enforce ordering Fuzzy Dice in pairs only.
                    int quantityOrdered;
                    isProperValue = Int32.TryParse(fieldValue, out quantityOrdered);
                    if (isProperValue)
                    {
                        if ((quantityOrdered % 2) != 0) // Odd number of product items ordered.
                        {
                            if ((string)this["Title"] == "Fuzzy Dice")
                            {
                                AddError("Item[Quantity]", "Fuzzy Dice must be ordered in pairs.
                                                                       No such thing as a Fuzzy Die!");
                            }
                            else
                            {
                                // Restriction on ordering in pairs doesn't apply to other products.
                                RemoveAllErrors("Item[Quantity]");
                            }
                        }
                        else
                        {
                            RemoveAllErrors("Item[Quantity]");
                        }
                    }
                    break;
                case "Fulfillment_x0020_Date":
                    // Determine whether fulfillment date is later than order date.
                    DateTime fulfillmentDate;
                    isProperValue = DateTime.TryParse(fieldValue, CultureInfo.CurrentCulture,
                                  DateTimeStyles.AssumeLocal, out fulfillmentDate);
                    if (isProperValue)
                    {
                        DateTime orderDate;
                        isProperValue = DateTime.TryParse((string)this["Order_x0020_Date"],
                                   CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal, out orderDate);
    
                        if (fulfillmentDate.CompareTo(orderDate) > 0)
                        {
                            RemoveAllErrors("Item[Fulfillment_x0020_Date]");
                        }
                        else
                        {
                            AddError("Item[Fulfillment_x0020_Date]",
                                    "Fulfillment Date must be later than Order Date.");
                        }
                    }
                    break;
                case "Contact_x0020_Number":
                    // Check that contact number is in an appropriate format.
                    Regex rx = new Regex(@"^\\(?([0-9]{3})\\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$");
                    if (rx.IsMatch(fieldValue))
                    {
                        RemoveAllErrors("Item[Contact_x0020_Number]");
                    }
                    else
                    {
                        //Specified Contact Number is not a valid phone number.
                        AddError("Item[Contact_x0020_Number]", "Specified Contact Number is invalid.");
                    }
                    break;
                default:
                    // Not adding custom validation for other fields.
                    break;
            }
        }
    
        //And then proceed with default validation from base class.
        base.Validate(fieldName, value);
    }
    

    请记住此代码示例指定的字段名称是基于表 1 中指定的产品预订列表示例属性。 (请注意,在 SharePoint Server 中列表字段的 XML 架构中,字段名称中的空格将替换为定义给定字段的 Field 元素的 Name 属性的字符串“x0020”。该模板使用 Field 元素的 Name 属性,因为它是在服务器上的 XML 架构中定义的,而不是 DisplayName 属性。) 可以通过查看 EditForm.xaml 中定义的 TextBox 对象的 Text 属性的 Binding 声明或检查 CamlQueryBuilderViewFields 字符串来标识要为其实现验证逻辑的字段名称 ListProvider.cs 文件中的 类。

  5. 保存文件。

只有当传递给 Validate 方法的 value 参数不是 null 或空字符串时,才会执行此示例中的自定义验证代码。 如表 1 所示,“履行日期”和“联系人号码”字段不需要包含数据(因为在 SharePoint Server 中,此示例定义了列表),因此不妨允许这些字段可以为空。 确定 value 参数是否为 null 的简单检查还不够,因为传递的值可以是零长度字符串(不等同于 null 值),而且对于此示例,并不要让零长度字符串对可以为空的字段无效。 “数量”和“履行日期”字段的验证逻辑包括额外检查传入的值,以确保它们的类型适当。 如果此处的初始检查 (在 switch 语句之前) 仅确认传入的值不是 null (而不是检查) 为零长度字符串的较窄条件,则如果值为零长度字符串,则仍不会执行这些验证,但如果传递的值是零长度字符串,则仍执行验证联系人号码字段数据的逻辑。 此示例希望允许“联系人号码”字段为空(零长度字符串),特别是当用户通过打开编辑表单开始编辑列表项时。

如果生成项目并将其部署到Windows Phone仿真器来运行该项目,则可以通过在应用的“编辑”窗体中将违反业务规则的数据输入到列表的字段中来测试验证逻辑。 (见图 3.)

图 3. 自定义验证错误提示

自定义验证错误提示

此示例中的代码如果只包含在 EditItemViewModel.cs 文件中,只有用户在编辑窗体上输入的数据的验证规则会被强制执行。 如果要在用户 添加新 项时以及编辑它们时强制实施验证规则,则必须在 NewItemViewModel.cs 文件 (的方法中包含 Validate() 相同的验证逻辑,或者最好使用包含此验证逻辑的函数创建单独的类文件,并从 Validate() EditItemViewModel.cs 文件和 NewItemViewModel.cs 文件) 中的方法调用相同的函数。

此示例中的验证逻辑通过提示用户所输数据不是规则允许的格式来强制执行给定的业务规则,但此代码不会拦截或更改输入的数据。 例如,在将数据保存到 SharePoint 列表之前要拦截并将电话号码设置为统一格式,可以对所输入的电话号码执自定义数据转换。 有关列表项字段的自定义数据转换的说明,请参阅如何:支持和转换 Windows Phone 应用程序的 SharePoint 字段类型

另请参阅