[WebInvoke(Method = " PUT " , UriTemplate = " {id} " )]
Customer UpdateCustomer( string id, Customer newCustomer);
这里从客户端传上来一个Customer类型的对象newCustomer,而不是完全把Customer分解成简单类型传上来。但是还是感觉这不是我想要的代码,因为这个Customer类型还是太“具体”,为每一个PUT动作都设计一个方法并不是我想要的。而且,如果离开了.NET平台,离开了DataContract,DataMember调用是不是会变的复杂呢(这个我现在也没有去研究,希望知道的兄弟指教一二),我心中希望的这种调用,最好就像Google Data API中的AtomEntry一样,使用一个AtomEntry.Update(),就可以把自已更新到服务器上去,而不是为每一个类型都去做自已的更新方法。既然Google能做到,那一定是实现的办法。
通过反复的查询MSDN,终于找到了一个可以被WCF当然数据契约接收的“通用”类型:
public abstract class SyndicationItemFormatter
很显然,这是一个抽象类,它的继承层次如下:
System.Object
System.ServiceModel.Syndication.SyndicationItemFormatter
System.ServiceModel.Syndication.Atom10ItemFormatter
System.ServiceModel.Syndication.Rss20ItemFormatter
再进一步,又发现了下面的这个类型:
where TSyndicationItem : new (), SyndicationItem
MSDN解释如下:
一个用于在 SyndicationItem派生类与 Atom 1.0 格式之间来回序列化的类。
备注:
使用此类可以序列化SyndicationItem 派生类的实例,以及从包含 Atom 1.0 项的 XML 文档创建SyndicationFeed 派生类的实例。如果必须序列化SyndicationItem实例,请改用Atom10ItemFormatter格式化程序。
如果把Atom10ItemFormatter<TSyndicationItem>做为WCF服务方法的参数类型,再使用HTTP 的PUT方式把数据推到WCF服务的方法上,这个Atom10ItemFormatter<TSyndicationItem>应该会将推进来的XML数据自动转换成SyndicationItem对象吧,试试看:
随例建一个Syndication Service项目,然后将IFeed1.cs修改为如下代码所示:
[ServiceKnownType( typeof (Atom10FeedFormatter))]
[ServiceKnownType( typeof (Rss20FeedFormatter))]
public interface IFeed1
{
[OperationContract]
[WebGet(UriTemplate = " get " , BodyStyle = WebMessageBodyStyle.Bare)]
SyndicationFeedFormatter CreateFeed();
[OperationContract]
[WebInvoke(Method = " PUT " , RequestFormat = WebMessageFormat.Xml, UriTemplate = " up " )]
void Update(Atom10ItemFormatter < SyndicationItem > item);
}
接下来再修改Feed1.cs,为其添加Update方法:
{
using (System.IO.StreamWriter file = new System.IO.StreamWriter( @" C:\a.txt " , true ))
{
file.WriteLine(item.Item.Title.Text);
}
}
为了观察是否得到了客户端PUT来的数据,我做了一个简单的Log,把PUT来的SyndicationItem的Title写入到一个文本文件。
有了服务端,还得有个客户端,新建一个控制台应用程序,将main.cs修改为如下所示:
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create( " http://localhost:8731/Design_Time_Addresses/RESTfulTest/Feed1/up " );
req.Method = " PUT " ;
SyndicationItem item = new SyndicationItem( " think8848 " , " Item Content " , new Uri( " http://Item/Alternate/Link " ), " itemID " , DateTimeOffset.Now);
MemoryStream ms = new MemoryStream();
XmlWriter writer = XmlWriter.Create(ms);
item.SaveAsAtom10(writer);
writer.Close();
req.ContentLength = ms.Length;
req.ContentType = " text/html " ;
Stream sw = req.GetRequestStream();
sw.Write(ms.ToArray(), 0 , ( int )ms.Length);
WebResponse resp = req.GetResponse();
Stream s = resp.GetResponseStream();
StreamReader sr = new StreamReader(s);
Console.WriteLine(sr.ReadToEnd());
resp.Close();
Console.ReadLine();
Go!Go!Go! Start new instance
观察下c:\a.txt中有没有东西:
示例代码下载
参考文章:http://social.msdn.microsoft.com/Forums/en/wcf/thread/c2f7a08e-3af8-4ea6-8eab-03eb07951de4