假设我有一个具有名字,姓氏和年龄的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序列化过程中挂钩的原因。
答案 0 :(得分:5)
在使用WCF时,通常不使用XML。您使用对象,并让WCF根据配置序列化对象。这样,相同的服务可以使用SOAP over HTTP,或通过TCP / IP二进制,或其他任何东西,都使用相同的代码。
答案 1 :(得分:2)
查看IExtensibleDataObject
interface - 可能就是您所需要的!
它允许WCF服务“隐藏”任何进来的额外信息,并在响应服务调用时将其传递回调用者,而不知道它存储的确切内容。它通常用于对服务进行版本控制 - 因此,如果新版本的服务需要其他参数,那么这些参数也可以传递给旧服务,并暂时存储在服务实现的ExtensionDataObject
中。 / p>