.net 如何使用WCF和EntLib验证块识别验证失败的记录? 问题:

.net 如何使用WCF和EntLib验证块识别验证失败的记录? 问题:,.net,wcf,validation,enterprise-library,.net,Wcf,Validation,Enterprise Library,我有一个WCF Web服务,客户可以使用它上传多个数据记录。为了验证数据,我使用企业库验证块。记录可以嵌套在几层深处 问题: 如何识别验证失败的记录 例子: 考虑以下数据结构。每个大陆可以有多个国家,每个国家可以有多个城市 大陆 名字 国家 名字 城市 名字 市长 当某个城市的市长验证失败时,我想知道该验证失败的城市、国家和地区。我认为您可能需要编写自己的验证程序,其中包含返回对象树并生成适当验证错误消息所需的逻辑。有关更多信息,请参阅本文: 我认为您可能需要编写自己的验证

我有一个WCF Web服务,客户可以使用它上传多个数据记录。为了验证数据,我使用企业库验证块。记录可以嵌套在几层深处

问题: 如何识别验证失败的记录

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

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

当某个城市的市长验证失败时,我想知道该验证失败的城市、国家和地区。

我认为您可能需要编写自己的验证程序,其中包含返回对象树并生成适当验证错误消息所需的逻辑。有关更多信息,请参阅本文:


我认为您可能需要编写自己的验证器,其中包含返回对象树并生成适当的验证错误消息所需的逻辑。有关更多信息,请参阅本文:


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

设置WCF集成:
(Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF)

创建一个简单的标记属性: 将放在标识数据记录的属性上

创建一个接口: 这是为了在上面的示例中从城市记录到国家记录的引用,以便链上的所有标识符也包括在内

修改
ValidationParameterInspector
要对所有输入进行爬网并使用如下方式设置
反向参考

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
通过像这样的反向引用进入记录树

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();
}
并将其放入
ValidationKDetail
Details.Key
。到目前为止,这个设置还没有完成


在Web服务中 现在需要做的就是在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; }
}

真是个怪物…

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

设置WCF集成:
(Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF)

创建一个简单的标记属性: 将放在标识数据记录的属性上

创建一个接口: 这是为了在上面的示例中从城市记录到国家记录的引用,以便链上的所有标识符也包括在内

修改
ValidationParameterInspector
要对所有输入进行爬网并使用如下方式设置
反向参考

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
通过像这样的反向引用进入记录树

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();
}
并将其放入
ValidationKDetail
Details.Key
。到目前为止,这个设置还没有完成


在Web服务中 现在需要做的就是在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; }
}

多么可怕的…

您是否收到“此故障的创建者未指定异常”消息?Sortof。我修改了集成,用一条类似于此处建议的细节替换了这条丑陋的消息:此消息按预期显示。您是否收到“此故障的创建者未指定异常”消息?Sortof。我修改了集成,用一个类似于此处建议的细节替换了这个丑陋的消息:并且这个消息按预期显示。