【问题标题】:How do I check if an anonymous object properties are not empty C#如何检查匿名对象属性是否为空 C#
【发布时间】:2017-12-14 22:18:45
【问题描述】:

我有一个 WebApi,它有一些接受 XMLDocument 值的操作方法。在这些函数中,我将该 XML 转换为 AnonymousObject,然后,我执行我的逻辑。

现在,我得到了带有空属性的 XML,我需要检查该匿名对象中的所有属性是否为空或空,我在那里做了一些事情,但它没有用,虽然,我传递了一个带有空属性的 XML。

<Students>
    <Student ID="" Name="" />
    <Student ID="" Name="" />
</Students>

这是我得到的 XML 输入示例,还有其他一些相同的形式,因此,我编写了一个函数,在将 XML 反序列化为匿名对象后检查属性是否为空,如下所示:

//This handles the conversion from XML to the anonymous object

XDocument doc;
using (var sr = new StringReader(request.InnerXml))
{
    doc = XDocument.Load(sr);
}

var clientList = doc.Descendants()
    .Where(d => string.Equals(d.Name.LocalName, "Student", StringComparison.OrdinalIgnoreCase))
    .Select(
        d =>
            new
            {
                studentId = d.Attributes().SingleOrDefault(a =>
                        string.Equals(a.Name.LocalName, "ID", StringComparison.OrdinalIgnoreCase))
                    ?.Value,
                studentName = d.Attributes().SingleOrDefault(a =>
                        string.Equals(a.Name.LocalName, "Name", StringComparison.OrdinalIgnoreCase))
                    ?.Value
            }).ToList();

然后我写了一个函数来验证匿名对象的属性,都应该有一个值,但是如果我传递了上面的 XML,它将返回 FALSE 就好像没有空值的属性一样:

public static bool IsAnyNullOrEmpty(object objectToBeChecked)
{
    try
    {
        foreach (PropertyInfo pi in objectToBeChecked.GetType().GetProperties())
        {
            if (pi.PropertyType == typeof(string))
            {
                string value = (string)pi.GetValue(objectToBeChecked);
                if (string.IsNullOrEmpty(value))
                {
                    return true;
                }
            }
        }
        return false;
        //return objectToBeChecked.GetType().GetProperties()
        //    .Where(pi => pi.GetValue(objectToBeChecked) is string)
        //    .Select(pi => (string) pi.GetValue(objectToBeChecked))
        //    .Any(string.IsNullOrEmpty);
    }
    catch (Exception ex)
    {
        return true;
    }
}

有什么建议吗?

编辑#1

在调试时我注意到:

  • 属性名称:&lt;&gt;f__AnonymousType3`1
  • 属性类型:Name = "&lt;&gt;f__AnonymousType3`1" FullName = "&lt;&gt;f__AnonymousType3`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"

【问题讨论】:

  • 你用过调试器吗?
  • 你为什么不创建一个类?尽管您可以在方法中提供一个匿名类型的实例,但这样做并没有真正意义。特别是在反序列化文件时,您对该文件中的对象的外观有一些字符串知识。隐藏这些信息是个坏主意。
  • @HimBromBeere,这个 api 控制器有大约 30 个动作方法,所有这些方法都接收不同的 XML 格式,这意味着我将有大约 30 个映射类用于传入的 XML 输入,这就像一个让我头疼,所以,我选择了匿名对象
  • 我看不出这会让人头疼。相反,您在尝试读取这些匿名对象时会遇到问题,正如您已经注意到的那样。我想你以后想以某种方式处理这些对象,所以你不仅要验证它们,还要在之后读取它们的属性,你会一次又一次地循环这些属性。如果您一开始就有类型,您就可以直接知道对象公开了哪些成员。
  • 让我继续说下去。在你验证了你的对象之后,你在做什么呢?

标签: c# xml anonymous-types


【解决方案1】:

我强烈建议为此使用命名类而不是匿名类。显然,您对 xml 中的实例公开的属性有一些深入的了解,因此将这些知识隐藏起来是没有用的。

想象有一天,您不仅需要字符串属性,还需要数字。然后,您必须重新发明大部分逻辑,不仅是验证,而且只是与对象的实际工作

我想你想做的不仅仅是验证你的对象。你肯定想和他们一些事情。为此,您需要知道他们公开了哪些成员。在您当前的实现中,它们只是objects,不会向客户公开太多。所以为了做任何事情,你需要这样的东西:

var a = ((theType) myInstance).StudentName;

但是您已经丢失了关于 theType 究竟是什么的所有信息,所以您可以对对象做的所有事情就是调用 ToStringEquals 和其他一些从 object 派生的成员。

在您的特殊情况下,您已经知道 xml 中的实例具有 StudentName- 和 studentId- 属性。那你为什么要把它扔掉,假装不知道呢?

截至MSDN

要将匿名类型或包含匿名类型的集合作为参数传递给方法,可以将参数声明为类型对象。然而,这样做违背了强类型的目的。如果你必须 存储查询结果或将它们传递到方法边界之外,考虑 使用普通的命名结构或类而不是匿名类型。

【讨论】:

  • 谢谢...您的回答对我很有启发,它帮助我找到了解决问题的方法。
【解决方案2】:

我是这样解决的:

public static bool IsAnyNullOrEmpty(object objectToBeChecked, params string[] parametersToBeChecked)
{
    foreach (var obj in (IEnumerable)objectToBeChecked)
    {
        foreach (var pi in obj.GetType().GetProperties())
        {
            if (parametersToBeChecked.Contains(pi.Name))
            {
                var value = (string)pi.GetValue(obj);
                if (string.IsNullOrEmpty(value))
                {
                    return true;
                }
            }
        }
    }

    return false;
}

这将获取您要检查的对象(匿名对象)和属性名称,这对我有用。

【讨论】:

    【解决方案3】:

    如果你想以某种方法传递你的对象,你需要使用一个具体的类实现。 复制您的 xml 结构并让 Visual Studio 为您创建一个反序列化类。 编辑 -> 选择性粘贴 -> 将 Xml 粘贴为类

    如果您知道您的 Xml 结构,为什么要丢失这些信息。

    【讨论】:

    • 我这里只有大约 30 个 XML 结构,这意味着我将获得大约 30 个模型,我只是想避免这种情况
    猜你喜欢
    • 2014-08-22
    • 2020-09-21
    • 1970-01-01
    • 2014-05-06
    • 2017-07-27
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多