WCF 上的 DataContract 和层次结构问题

发布于 2024-11-26 08:31:55 字数 562 浏览 1 评论 0原文

我的 wcf 项目中的对象有问题。 我可以说这个对象:

[DataContract(Name="ClassA")]
public class Person{
   //---attributes---
}

[DataContract(Name="ClassB")]
public class Men : Person{
  //---attributes---
}

其中 ClassB 是另一侧 ClassA 的子级。 然后我有一个 post 方法:

[OperationContract]
[WebInvoke(UriTemplate= "Person", ResponseFormat = WebMessageFormat.Json, Method= "POST")]
public string PostPerson(Person person) {
    if(person is Men){
       //code...
    }
}

问题是我收到了这个人(在另一边,他们将我作为 ClassB 发送),但这个人是 Men 返回 false.. 为什么?

i have a problem with an object in my wcf project.
I have lets say this object:

[DataContract(Name="ClassA")]
public class Person{
   //---attributes---
}

[DataContract(Name="ClassB")]
public class Men : Person{
  //---attributes---
}

Where ClassB is child of ClassA on the other side.
Then i have a method that is post:

[OperationContract]
[WebInvoke(UriTemplate= "Person", ResponseFormat = WebMessageFormat.Json, Method= "POST")]
public string PostPerson(Person person) {
    if(person is Men){
       //code...
    }
}

The thing is that i receive the person (in the other side, they sendme as a ClassB) but the person is Men returns false.. why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

揽月 2024-12-03 08:31:55

您需要将 [ServiceKnownType(typeof(Men))] 属性添加到 PostPerson 方法。

You need to add the [ServiceKnownType(typeof(Men))] attribute to the PostPerson method.

爱情眠于流年 2024-12-03 08:31:55

正如瑞安·格罗斯(Ryan Gross)提到的,你需要男人成为一种众所周知的类型。 这里有一个类似的问题/答案。链接文章中未提及的一个选项是已知类型属性。这是我过去使用过的代码示例。前提条件是此类是所有数据协定的基类,并且所有数据协定都位于同一个程序集中:

/// <summary>
///   Base class for all data contracts.
/// </summary>
[DataContract(Name = "Base", Namespace = "your namespace")]
[KnownType("GetKnownTypes")]
public class BaseDC : IExtensibleDataObject
{
  #region Constants and Fields

  /// <summary>
  ///   Instance used to control access to the known types list.
  /// </summary>
  private static readonly object _knownTypesLock = new object();

  /// <summary>
  ///   Classes derived from this class.  Needed to ensure proper functioning of the WCF data
  ///   constract serializer.
  /// </summary>
  private static List<Type> _knownTypes;

  #endregion

  #region Properties

  /// <summary>
  ///   Gets or sets an <c>ExtensionDataObject</c> that contains data that is not recognized as belonging to the
  ///   data contract.
  /// </summary>
  public ExtensionDataObject ExtensionData { get; set; }

  #endregion

  #region Public Methods

  /// <summary>
  ///   Enumerates the types in the assembly containing <c>BaseDC</c> that derive from <c>BaseDC</c>.
  /// </summary>
  /// <returns>List of <c>BaseDC</c>-derived types.</returns>
  [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate",
    Justification = "Not appropriate for a property.")]
  public static IEnumerable<Type> GetKnownTypes()
  {
    lock (_knownTypesLock)
    {
      if (_knownTypes == null)
      {
        _knownTypes = new List<Type>();
        Assembly contractsAssembly = Assembly.GetAssembly(typeof(BaseDC));
        Type[] assemblyTypes = contractsAssembly.GetTypes();
        foreach (Type assemblyType in assemblyTypes)
        {
          if (assemblyType.IsClass && !assemblyType.IsGenericType)
          {
            if (assemblyType.IsSubclassOf(typeof(BaseDC)))
            {
              _knownTypes.Add(assemblyType);
            }
          }
        }

        _knownTypes.Add(typeof(BaseDC));
      }

      return _knownTypes;
    }
  }

  #endregion
}

As Ryan Gross mentions, you need Men to be a known type. Here's a similar question/answer here on SO. One option not mentioned in the linked article is the KnownType attribute. Here's an example of code I've used in the past. The prerequisite is that this class is the base class for all of your data contracts and all of your data contracts are in the same assembly:

/// <summary>
///   Base class for all data contracts.
/// </summary>
[DataContract(Name = "Base", Namespace = "your namespace")]
[KnownType("GetKnownTypes")]
public class BaseDC : IExtensibleDataObject
{
  #region Constants and Fields

  /// <summary>
  ///   Instance used to control access to the known types list.
  /// </summary>
  private static readonly object _knownTypesLock = new object();

  /// <summary>
  ///   Classes derived from this class.  Needed to ensure proper functioning of the WCF data
  ///   constract serializer.
  /// </summary>
  private static List<Type> _knownTypes;

  #endregion

  #region Properties

  /// <summary>
  ///   Gets or sets an <c>ExtensionDataObject</c> that contains data that is not recognized as belonging to the
  ///   data contract.
  /// </summary>
  public ExtensionDataObject ExtensionData { get; set; }

  #endregion

  #region Public Methods

  /// <summary>
  ///   Enumerates the types in the assembly containing <c>BaseDC</c> that derive from <c>BaseDC</c>.
  /// </summary>
  /// <returns>List of <c>BaseDC</c>-derived types.</returns>
  [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate",
    Justification = "Not appropriate for a property.")]
  public static IEnumerable<Type> GetKnownTypes()
  {
    lock (_knownTypesLock)
    {
      if (_knownTypes == null)
      {
        _knownTypes = new List<Type>();
        Assembly contractsAssembly = Assembly.GetAssembly(typeof(BaseDC));
        Type[] assemblyTypes = contractsAssembly.GetTypes();
        foreach (Type assemblyType in assemblyTypes)
        {
          if (assemblyType.IsClass && !assemblyType.IsGenericType)
          {
            if (assemblyType.IsSubclassOf(typeof(BaseDC)))
            {
              _knownTypes.Add(assemblyType);
            }
          }
        }

        _knownTypes.Add(typeof(BaseDC));
      }

      return _knownTypes;
    }
  }

  #endregion
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文