我在哪里挂钩到WCF SOAP响应以生成要返回的对象的XML?

时间:2011-12-02 05:28:52

标签: xml wcf soap xml-serialization

假设我有一个具有名字,姓氏和年龄的Person对象。我想将此person对象发送到一个Web服务,该Web服务只知道并关心具有名字和姓氏的person对象。但我希望xml代表完整的人物对象,包括要发回的年龄。

我已经有了一种机制,可以将xml存储在幕后的对象中,并且可以简单地将xml提供给WCF,但我不想使用普通的XmlSerializer。我希望能够说“这里是xml。用肥皂包裹并发送”。

我打算使用WCF。我将在哪里挂钩来控制序列化?

更多详情

虽然这个问题的例子是人为的。它清楚地说明了我的问题。假设我有一个像这样的类的应用程序:

/* person A */
class Person {
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public int Age { get; set; }
}

我将此传递给Web服务。 Web服务知道编写为:

的不同Person类
/* person B */
class Person {
  public string FirstName { get; set; }
  public string LastName { get; set; }
}

该服务的方法具有以下方法签名:

Person SomeOperation(Person p);

当我从我的应用程序中调用此Web服务并将其传递给我的人员A版本时,Web服务接收它就好了。它忽略了Age属性。但是当它重新创建响应时,Age属性就会消失。

我理解为什么这种情况正在发生。 WCF将响应反序列化为实际的c#对象,因此丢弃随请求一起发送的额外XML。因此,没有Age属性可以发回。

我有一种机制来实际使用XML作为我的对象的后备存储。如果后备存储中存在该对象不需要的XML,则它只是位于那里并且未被使用。我希望在响应中发回用作后备存储的完整XML。

如果这是一个基本的c#应用程序,我可以简单地创建一个包含FirstName和LastName属性的IBasicPerson接口,并让Person类实现接口,如下面的代码:

public interface IBasicPerson {
  string FirstName { get; set; }
  string LastName { get; set; }
}

public class Person : IBasicPerson {
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public int Age { get; set; }
}

然后我可以在其他类中创建一个操作,该类获取并返回IBasicPerson接口:

public SomeClass {
  public IBasicPerson SomeOperation(IBasicPerson p) {
    /* do stuff */
    return p;
  }
}

当我打电话给它时,它不关心Age属性,信息也不会丢失。这是因为SomeOperation中的IBasicPerson和传入的实际Person实例都引用了完全相同的对象。但是,在通过线路进行WCF调用时不是这种情况。

从调用WCF服务的应用程序的角度来看,方法返回值中的对象与传入的对象不同。

我的XML后备存储解决了这个问题,但前提是我能弄明白如何防止它丢失。这就是为什么我要弄清楚我应该在WCF序列化过程中挂钩的原因。

2 个答案:

答案 0 :(得分:5)

在使用WCF时,通常不使用XML。您使用对象,并让WCF根据配置序列化对象。这样,相同的服务可以使用SOAP over HTTP,或通过TCP / IP二进制,或其他任何东西,都使用相同的代码。

答案 1 :(得分:2)

查看IExtensibleDataObject interface - 可能就是您所需要的!

它允许WCF服务“隐藏”任何进来的额外信息,并在响应服务调用时将其传递回调用者,而不知道它存储的确切内容。它通常用于对服务进行版本控制 - 因此,如果新版本的服务需要其他参数,那么这些参数也可以传递给旧服务,并暂时存储在服务实现的ExtensionDataObject中。 / p>