【问题标题】:Using XmlIgnore on generated partial classes在生成的部分类上使用 XmlIgnore
【发布时间】:2013-11-01 23:11:59
【问题描述】:

我有一个 LINQ 2 SQL 生成的类,我想通过 Web 服务公开。 有一些我不想使用的内部属性。

通常我会将 [XmlIgnore] 扔在那里,但因为属性在生成的一半中,所以我不能这样做。

我一直在研究在 this post 之后使用 MetadataType,它看起来应该允许我在另一个类中定义属性属性。

我的代码如下所示:

[MetadataType(typeof(ProspectMetaData))]
public partial class Prospect : ApplicationBaseObject
{
}

public class ProspectMetaData
{
     [XmlIgnore]
     public object CreatedDateTime { get; set; }

     [XmlIgnore]
     public object AmendedDateTime { get; set; }

     [XmlIgnore]
     public object Timestamp { get; set; }
}

我通过 Silverlight 项目中的 ASP.NET Web 服务引用它。

问题是 [XmlIgnore] 属性被忽略,这些属性正在被发送。

有没有人知道这里可能出了什么问题?最好的方法是什么?

【问题讨论】:

    标签: c# silverlight web-services attributes metadata


    【解决方案1】:

    您可以通过将自己的 XmlAttributeOverrides 传递给 XmlSerializer 来做到这一点,在 XmlAttributeOverrides 中,您可以将 XmlIgnore 更改为您希望的字段/属性,而无需触及 DBML 生成的代码,它就像一个魅力,使用相同的覆盖反序列化也...

    Refer this link了解更多信息

        // Create the XmlAttributeOverrides and XmlAttributes objects.
        XmlAttributeOverrides xOver = new XmlAttributeOverrides();
    
        XmlAttributes attrs = new XmlAttributes();
        attrs.XmlIgnore = true;
    
        /* Setting XmlIgnore to true overrides the XmlIgnoreAttribute
            applied to the following fields. Thus it will be serialized.*/
        xOver.Add(typeof(Prospect), "CreatedDateTime", attrs);
        xOver.Add(typeof(Prospect), "AmendedDateTime", attrs);
        xOver.Add(typeof(Prospect), "Timestamp", attrs);
    
        XmlSerializer xSer = new XmlSerializer(typeof(Prospect), xOver);
        TextWriter writer = new StreamWriter(outputFilePath);
        xSer.Serialize(writer, object);
    

    【讨论】:

    • 有没有办法为 Newtonsoft.Json JSON 序列化程序做到这一点?
    • @Dave,我不熟悉Newtonsoft.Json 来评论一下,如果它是从XmlSerializer 派生的,那么你也许可以...我使用XmlIgnore 的主要原因是为了避免循环引用,它似乎 Newtonsoft.Json 有一些 settings 来避免这种情况。
    【解决方案2】:

    AFAIK,XmlSerializer 不支持MetadataTypeAttribute(虽然它会很好 - 我只是从未检查过)。正如你所说,你不能在部分类中添加成员属性。

    一种选择可能是使生成的属性不公开(privateprotectedinternal) - 并将其命名为 TimestampStorage(等) - 然后重新公开它们(在部分类)在公共 API 上:

     [XmlIgnore]
     public object Timestamp {
         get {return TimestampStorage; }
         set {TimestampStorage = value; }
     }
     // and other properties
    

    (因为XmlSerializer 只查看公共 API)。这里最大的问题是 LINQ-to-SQL 查询(Where 等)只能对生成的列(TimestampStorage 等)起作用。我之前使用过这种方法,成员为internal,允许我的 DAL 类使用internal 属性……但这有点儿糊涂。

    【讨论】:

    • 看起来确实是这样,真是太可惜了。我无法控制生成属性的访问器,因此它并不能真正为我解决问题。我想我只需要使用代理类而不是发送我的业务对象。
    • 您必须在重新生成时重置访问级别。 :(
    • 感谢您的提示。 12 年后,XmlSerializer仍然不支持MetadataTypeAttribute
    【解决方案3】:

    我同意马克的观点。最简单的做法是将它们标记为内部。或者,您可以使用 [XmlIgnore] 在部分类中重新公开它们。顺便说一句,您可以控制 linq2sql 设计器中属性的可访问性。进入属性对话框,你会看到一个设置它们的地方

    【讨论】:

    • 我们实际上是在使用我们自己的代码生成工具来输出生成的一半,当我说 LINQ2SQL 时,它是最接近的并行。不过,这对其他人来说可能很方便。 +1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-27
    • 1970-01-01
    • 2015-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多