1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //------------------------------------------------------------
4 
5 namespace System.ServiceModel.Dispatcher
6 {
7     using System;
8     using System.Collections.Generic;
9     using System.ServiceModel;
10     using System.ServiceModel.Channels;
11     using System.ServiceModel.Description;
12     using System.Globalization;
13     using System.Text;
14 
15     class DemultiplexingDispatchMessageFormatter : IDispatchMessageFormatter
16     {
17         IDispatchMessageFormatter defaultFormatter;
18         Dictionary<WebContentFormat, IDispatchMessageFormatter> formatters;
19         string supportedFormats;
20 
DemultiplexingDispatchMessageFormatter(IDictionary<WebContentFormat, IDispatchMessageFormatter> formatters, IDispatchMessageFormatter defaultFormatter)21         public DemultiplexingDispatchMessageFormatter(IDictionary<WebContentFormat, IDispatchMessageFormatter> formatters, IDispatchMessageFormatter defaultFormatter)
22         {
23             if (formatters == null)
24             {
25                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("formatters");
26             }
27             this.formatters = new Dictionary<WebContentFormat, IDispatchMessageFormatter>();
28             foreach (WebContentFormat key in formatters.Keys)
29             {
30                 this.formatters.Add(key, formatters[key]);
31             }
32             this.defaultFormatter = defaultFormatter;
33         }
34 
DeserializeRequest(Message message, object[] parameters)35         public void DeserializeRequest(Message message, object[] parameters)
36         {
37             if (message == null)
38             {
39                 return;
40             }
41             WebContentFormat format;
42             IDispatchMessageFormatter selectedFormatter;
43             if (TryGetEncodingFormat(message, out format))
44             {
45                 this.formatters.TryGetValue(format, out selectedFormatter);
46                 if (selectedFormatter == null)
47                 {
48                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR2.GetString(SR2.UnrecognizedHttpMessageFormat, format, GetSupportedFormats())));
49                 }
50             }
51             else
52             {
53                 selectedFormatter = this.defaultFormatter;
54                 if (selectedFormatter == null)
55                 {
56                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR2.GetString(SR2.MessageFormatPropertyNotFound3)));
57                 }
58             }
59             selectedFormatter.DeserializeRequest(message, parameters);
60         }
61 
SerializeReply(MessageVersion messageVersion, object[] parameters, object result)62         public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
63         {
64             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.GetString(SR2.SerializingReplyNotSupportedByFormatter, this)));
65         }
66 
GetSupportedFormats(IEnumerable<WebContentFormat> formats)67         internal static string GetSupportedFormats(IEnumerable<WebContentFormat> formats)
68         {
69             StringBuilder sb = new StringBuilder();
70             int i = 0;
71             foreach (WebContentFormat format in formats)
72             {
73                 if (i > 0)
74                 {
75                     sb.Append(CultureInfo.CurrentCulture.TextInfo.ListSeparator);
76                     sb.Append(" ");
77                 }
78                 sb.Append("'" + format.ToString() + "'");
79                 ++i;
80             }
81             return sb.ToString();
82         }
83 
TryGetEncodingFormat(Message message, out WebContentFormat format)84         internal static bool TryGetEncodingFormat(Message message, out WebContentFormat format)
85         {
86             object prop;
87             message.Properties.TryGetValue(WebBodyFormatMessageProperty.Name, out prop);
88             WebBodyFormatMessageProperty formatProperty = prop as WebBodyFormatMessageProperty;
89             if (formatProperty == null)
90             {
91                 format = WebContentFormat.Default;
92                 return false;
93             }
94             format = formatProperty.Format;
95             return true;
96         }
97 
GetSupportedFormats()98         string GetSupportedFormats()
99         {
100             if (this.supportedFormats == null)
101             {
102                 this.supportedFormats = GetSupportedFormats(this.formatters.Keys);
103             }
104             return this.supportedFormats;
105         }
106     }
107 }
108 
109