From 36942bc07bb1050abfc1461938e4d78e2b530124 Mon Sep 17 00:00:00 2001 From: Atsushi Eno Date: Wed, 2 Sep 2009 08:53:30 +0000 Subject: [PATCH] 2009-09-02 Atsushi Enomoto * WebHttpDispatchOperationSelector.cs : use common extension method. * WebMessageFormatter.cs : support WebMessageBodyStyle(.Wrapped*). Cache serializers. svn path=/trunk/mcs/; revision=141102 --- .../System.ServiceModel.Dispatcher/ChangeLog | 6 ++ .../WebHttpDispatchOperationSelector.cs | 16 +--- .../WebMessageFormatter.cs | 75 ++++++++++++++----- 3 files changed, 65 insertions(+), 32 deletions(-) diff --git a/mcs/class/System.ServiceModel.Web/System.ServiceModel.Dispatcher/ChangeLog b/mcs/class/System.ServiceModel.Web/System.ServiceModel.Dispatcher/ChangeLog index 6912026141e..5dab157b8bd 100644 --- a/mcs/class/System.ServiceModel.Web/System.ServiceModel.Dispatcher/ChangeLog +++ b/mcs/class/System.ServiceModel.Web/System.ServiceModel.Dispatcher/ChangeLog @@ -1,3 +1,9 @@ +2009-09-02 Atsushi Enomoto + + * WebHttpDispatchOperationSelector.cs : use common extension method. + * WebMessageFormatter.cs : support WebMessageBodyStyle(.Wrapped*). + Cache serializers. + 2009-07-28 Atsushi Enomoto * WebMessageFormatter.cs : apply OutgoingRequest if available. diff --git a/mcs/class/System.ServiceModel.Web/System.ServiceModel.Dispatcher/WebHttpDispatchOperationSelector.cs b/mcs/class/System.ServiceModel.Web/System.ServiceModel.Dispatcher/WebHttpDispatchOperationSelector.cs index beec9cdd5ad..67735b801a3 100644 --- a/mcs/class/System.ServiceModel.Web/System.ServiceModel.Dispatcher/WebHttpDispatchOperationSelector.cs +++ b/mcs/class/System.ServiceModel.Web/System.ServiceModel.Dispatcher/WebHttpDispatchOperationSelector.cs @@ -55,7 +55,7 @@ namespace System.ServiceModel.Dispatcher table = new UriTemplateTable (endpoint.Address.Uri); foreach (OperationDescription od in endpoint.Contract.Operations) { - WebAttributeInfo info = GetWebAttributeInfo (od); + WebAttributeInfo info = od.GetWebAttributeInfo (); if (info != null) table.KeyValuePairs.Add (new TemplateTablePair (info.BuildUriTemplate (od, null), od)); } @@ -88,19 +88,5 @@ namespace System.ServiceModel.Dispatcher } return od != null ? od.Name : String.Empty; } - - WebAttributeInfo GetWebAttributeInfo (OperationDescription od) - { - foreach (IOperationBehavior ob in od.Behaviors) { - WebAttributeInfo info = null; - var wg = ob as WebGetAttribute; - if (wg != null) - return wg.Info; - var wi = ob as WebInvokeAttribute; - if (wi != null) - return wi.Info; - } - return null; - } } } diff --git a/mcs/class/System.ServiceModel.Web/System.ServiceModel.Dispatcher/WebMessageFormatter.cs b/mcs/class/System.ServiceModel.Web/System.ServiceModel.Dispatcher/WebMessageFormatter.cs index 6dac240c24e..67d3c56d8eb 100644 --- a/mcs/class/System.ServiceModel.Web/System.ServiceModel.Dispatcher/WebMessageFormatter.cs +++ b/mcs/class/System.ServiceModel.Web/System.ServiceModel.Dispatcher/WebMessageFormatter.cs @@ -4,7 +4,7 @@ // Author: // Atsushi Enomoto // -// Copyright (C) 2008 Novell, Inc (http://www.novell.com) +// Copyright (C) 2008,2009 Novell, Inc (http://www.novell.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -35,6 +35,7 @@ using System.ServiceModel.Channels; using System.ServiceModel.Dispatcher; using System.ServiceModel.Web; using System.Text; +using System.Xml; namespace System.ServiceModel.Description { @@ -80,6 +81,21 @@ namespace System.ServiceModel.Description get { return info; } } + public WebMessageBodyStyle BodyStyle { + get { return info.IsBodyStyleSetExplicitly ? info.BodyStyle : behavior.DefaultBodyStyle; } + } + + public bool IsResponseBodyWrapped { + get { + switch (BodyStyle) { + case WebMessageBodyStyle.Wrapped: + case WebMessageBodyStyle.WrappedResponse: + return true; + } + return false; + } + } + public OperationDescription Operation { get { return operation; } } @@ -124,6 +140,31 @@ namespace System.ServiceModel.Description throw new SystemException ("INTERNAL ERROR: no corresponding message description for the specified direction: " + dir); } + protected XmlObjectSerializer GetSerializer (WebContentFormat msgfmt) + { + switch (msgfmt) { + case WebContentFormat.Xml: + return GetSerializer (ref xml_serializer, t => new DataContractSerializer (t)); + break; + case WebContentFormat.Json: + return GetSerializer (ref json_serializer, t => new DataContractJsonSerializer (t)); + break; + default: + throw new NotImplementedException (); + } + } + + XmlObjectSerializer xml_serializer, json_serializer; + + XmlObjectSerializer GetSerializer (ref XmlObjectSerializer serializer, Func f) + { + if (serializer == null) { + MessageDescription md = GetMessageDescription (MessageDirection.Output); + serializer = f (md.Body.ReturnValue.Type); + } + return serializer; + } + internal class RequestClientFormatter : WebClientMessageFormatter { public RequestClientFormatter (OperationDescription operation, ServiceEndpoint endpoint, QueryStringConverter converter, WebHttpBehavior behavior) @@ -217,24 +258,24 @@ namespace System.ServiceModel.Description if (!message.Properties.ContainsKey (pname)) throw new SystemException ("INTERNAL ERROR: it expects WebBodyFormatMessageProperty existence"); var wp = (WebBodyFormatMessageProperty) message.Properties [pname]; - MessageDescription md = GetMessageDescription (MessageDirection.Output); - XmlObjectSerializer serializer = null; - switch (wp.Format) { - case WebContentFormat.Xml: - serializer = new DataContractSerializer (md.Body.ReturnValue.Type); - break; - case WebContentFormat.Json: - serializer = new DataContractJsonSerializer (md.Body.ReturnValue.Type); - break; - case WebContentFormat.Raw: - default: - throw new NotImplementedException (); - } + var serializer = GetSerializer (wp.Format); // FIXME: handle ref/out parameters - return serializer.ReadObject (message.GetReaderAtBodyContents (), false); + var md = GetMessageDescription (MessageDirection.Output); + + var reader = message.GetReaderAtBodyContents (); + + if (IsResponseBodyWrapped && md.Body.WrapperName != null) + reader.ReadStartElement (md.Body.WrapperName, md.Body.WrapperNamespace); + + var ret = serializer.ReadObject (reader, false); + + if (IsResponseBodyWrapped && md.Body.WrapperName != null) + reader.ReadEndElement (); + + return ret; } } @@ -275,11 +316,11 @@ namespace System.ServiceModel.Description XmlObjectSerializer serializer = null; switch (msgfmt) { case WebMessageFormat.Xml: - serializer = new DataContractSerializer (md.Body.ReturnValue.Type); + serializer = GetSerializer (WebContentFormat.Xml); mediaType = "application/xml"; break; case WebMessageFormat.Json: - serializer = new DataContractJsonSerializer (md.Body.ReturnValue.Type); + serializer = GetSerializer (WebContentFormat.Json); mediaType = "application/json"; break; } -- 2.25.1