【问题标题】:How to identify in which record the validation failed using WCF and EntLib Validation Block?如何使用 WCF 和 EntLib 验证块识别验证失败的记录?
【发布时间】:2010-11-26 11:36:05
【问题描述】:

问题:

我有一个 WCF Web 服务,客户可以使用它上传多个数据记录。为了验证数据,我使用 Enterprise Library Validation Block。记录可以嵌套好几层。

问题:

如何识别验证失败的记录?

示例:

考虑以下数据结构。每个大陆可以有多个国家,每个国家可以有多个城市。

  • 大陆
    • 姓名
    • 国家
      • 姓名
      • 城市
        • 姓名
        • 市长

当一个城市的市长验证失败时,我想知道它失败的城市、国家和大陆。

【问题讨论】:

  • 您是否收到“此故障的创建者未指定异常”消息?
  • 排序。我修改了集成,用类似于此处建议的细节之一替换了那个丑陋的消息:stackoverflow.com/questions/1164602/… 并且此消息按预期显示。

标签: .net wcf validation enterprise-library


【解决方案1】:

我通过执行以下操作解决了我的问题:

设置 WCF 集成:

(Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF)

创建一个简单的标记属性:

public class ValidationKeyAttribute : Attribute
{
}

将放在标识数据记录的属性上。

创建接口:

public interface IValidationBackReference
{
    object BackReference { get; set; }
}

这是为了在上例中从城市记录到国家记录的引用,以便链上的所有标识符也被包括在内

修改ValidationParameterInspector中的BeforeCall()方法

抓取所有输入并使用以下内容设置BackReference

private void SearchForBackReferences(object input, object backReference)
{
    if (input == null)
    {
        return;
    }
    Type t = input.GetType();
    if (t.IsArray)
    {
        Object[] inputs = (object[])input;
        SearchForBackReferences(inputs, backReference);
    }
    else if (input is IValidationBackReference)
    {
        foreach (PropertyInfo info in t.GetProperties())
        {
            object value = info.GetValue(input, null);
            SearchForBackReferences(value, input);
        }
        ((IValidationBackReference)input).BackReference = backReference;
    }
}

private void SearchForBackReferences(object[] inputs, object backReference)
{
    if(inputs==null)
    {
        return;
    }
    foreach (object input in inputs)
    {   
        SearchForBackReferences(input, backReference);
    }
}

修改ValidationParameterInspector中的CreateValidationDetail方法

通过 BackReferences 使用类似这样的方式向上记录树

private static string FindKey(object target)
{
    StringBuilder result = new StringBuilder();
    if( target == null )
    {
        return result.ToString();
    }
    if(target is IValidationBackReference)
    {
        result.Append(FindKey(((IValidationBackReference) target).BackReference));
    }
    Type t = target.GetType();
    foreach (var info in t.GetProperties())
    {
        if (Attribute.IsDefined(info, typeof(ValidationKeyAttribute)))
        {
            object objectValue = info.GetValue(target, null);
            string stringValue = "(null)";
            if (objectValue != null)
            {
                stringValue = objectValue.ToString();
            }
            result.Append(string.Format("{0} = '{1}'; ",info.Name, stringValue));
        }
    }
    return result.ToString();
}

并将其放入ValidationKDetailDetails.Key 中。到目前为止的设置。


在网络服务中

您现在要做的就是在 Web 服务使用的类上实现 IValidationBackReference 接口,并将 [ValidationKey] 属性放在适当的属性上。

上面的例子看起来像:

public class Continent : IValidationBackReference
{
    public object BackReference { get; set; }
    [ValidationKey]
    public string Name { get; set; }

    public Country[] Countries{ get; set; }
}

public class Country : IValidationBackReference
{
    public object BackReference { get; set; }
    [ValidationKey]
    public string Name { get; set; }

    public City[] Cities { get; set; }
}

public class City : IValidationBackReference
{
    public object BackReference { get; set; }
    [ValidationKey]
    public string Mayor { get; set; }
}

真是个怪物……

【讨论】:

    【解决方案2】:

    我认为您可能需要编写自己的验证器,其中包含备份对象树并生成合适的验证错误消息所需的逻辑。查看这篇文章了解更多信息:

    http://www.codeproject.com/KB/cs/VABCustomValidator.aspx

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-21
      • 1970-01-01
      • 2014-06-08
      • 2017-01-10
      • 2016-02-08
      • 1970-01-01
      相关资源
      最近更新 更多