| | | 1 | | // Licensed to the .NET Foundation under one or more agreements. |
| | | 2 | | // The .NET Foundation licenses this file to you under the MIT license. |
| | | 3 | | |
| | | 4 | | using System; |
| | | 5 | | using System.Collections.Generic; |
| | | 6 | | using System.Text; |
| | | 7 | | using System.Xml; |
| | | 8 | | using CoreWCF.Channels; |
| | | 9 | | using CoreWCF.Description; |
| | | 10 | | |
| | | 11 | | namespace CoreWCF.Dispatcher |
| | | 12 | | { |
| | | 13 | | internal class UriTemplateClientFormatter : IClientMessageFormatter |
| | | 14 | | { |
| | 0 | 15 | | public object DeserializeReply(Message message, object[] parameters) => throw new PlatformNotSupportedException( |
| | | 16 | | |
| | 0 | 17 | | public Message SerializeRequest(MessageVersion messageVersion, object[] parameters) => throw new PlatformNotSupp |
| | | 18 | | |
| | | 19 | | internal static string GetUTStringOrDefault(OperationDescription operationDescription) |
| | | 20 | | { |
| | 489 | 21 | | string utString = WebHttpBehavior.GetWebUriTemplate(operationDescription); |
| | 489 | 22 | | if (utString == null && WebHttpBehavior.GetWebMethod(operationDescription) == WebHttpBehavior.GET) |
| | | 23 | | { |
| | 0 | 24 | | utString = MakeDefaultGetUTString(operationDescription); |
| | | 25 | | } |
| | | 26 | | |
| | 489 | 27 | | if (utString == null) |
| | | 28 | | { |
| | 0 | 29 | | utString = operationDescription.Name; // note: not + "/*", see 8988 and 9653 |
| | | 30 | | } |
| | | 31 | | |
| | 489 | 32 | | return utString; |
| | | 33 | | } |
| | | 34 | | |
| | | 35 | | internal static void Populate(out Dictionary<int, string> pathMapping, |
| | | 36 | | out Dictionary<int, KeyValuePair<string, Type>> queryMapping, |
| | | 37 | | out int totalNumUTVars, |
| | | 38 | | out UriTemplate uriTemplate, |
| | | 39 | | OperationDescription operationDescription, |
| | | 40 | | QueryStringConverter qsc, |
| | | 41 | | string contractName) |
| | | 42 | | { |
| | 326 | 43 | | pathMapping = new Dictionary<int, string>(); |
| | 326 | 44 | | queryMapping = new Dictionary<int, KeyValuePair<string, Type>>(); |
| | 326 | 45 | | string utString = GetUTStringOrDefault(operationDescription); |
| | 326 | 46 | | uriTemplate = new UriTemplate(utString); |
| | 326 | 47 | | List<string> neededPathVars = new List<string>(uriTemplate.PathSegmentVariableNames); |
| | 326 | 48 | | List<string> neededQueryVars = new List<string>(uriTemplate.QueryValueVariableNames); |
| | 326 | 49 | | Dictionary<string, byte> alreadyGotVars = new Dictionary<string, byte>(StringComparer.OrdinalIgnoreCase); |
| | 326 | 50 | | totalNumUTVars = neededPathVars.Count + neededQueryVars.Count; |
| | 912 | 51 | | for (int i = 0; i < operationDescription.Messages[0].Body.Parts.Count; ++i) |
| | | 52 | | { |
| | 130 | 53 | | MessagePartDescription mpd = operationDescription.Messages[0].Body.Parts[i]; |
| | 130 | 54 | | string parameterName = XmlConvert.DecodeName(mpd.Name); |
| | 130 | 55 | | if (alreadyGotVars.ContainsKey(parameterName)) |
| | | 56 | | { |
| | 0 | 57 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( |
| | 0 | 58 | | SR.Format(SR.UriTemplateVarCaseDistinction, XmlConvert.DecodeName(operationDescription.Name), co |
| | | 59 | | } |
| | | 60 | | |
| | 130 | 61 | | List<string> neededPathCopy = new List<string>(neededPathVars); |
| | 452 | 62 | | foreach (string pathVar in neededPathCopy) |
| | | 63 | | { |
| | 96 | 64 | | if (string.Compare(parameterName, pathVar, StringComparison.OrdinalIgnoreCase) == 0) |
| | | 65 | | { |
| | 80 | 66 | | if (mpd.Type != typeof(string)) |
| | | 67 | | { |
| | 0 | 68 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( |
| | 0 | 69 | | SR.Format(SR.UriTemplatePathVarMustBeString, XmlConvert.DecodeName(operationDescription. |
| | | 70 | | } |
| | 80 | 71 | | pathMapping.Add(i, parameterName); |
| | 80 | 72 | | alreadyGotVars.Add(parameterName, 0); |
| | 80 | 73 | | neededPathVars.Remove(pathVar); |
| | | 74 | | } |
| | | 75 | | } |
| | | 76 | | |
| | 130 | 77 | | List<string> neededQueryCopy = new List<string>(neededQueryVars); |
| | 292 | 78 | | foreach (string queryVar in neededQueryCopy) |
| | | 79 | | { |
| | 16 | 80 | | if (string.Compare(parameterName, queryVar, StringComparison.OrdinalIgnoreCase) == 0) |
| | | 81 | | { |
| | 16 | 82 | | if (!qsc.CanConvert(mpd.Type)) |
| | | 83 | | { |
| | 0 | 84 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( |
| | 0 | 85 | | SR.Format(SR.UriTemplateQueryVarMustBeConvertible, XmlConvert.DecodeName(operationDescri |
| | | 86 | | } |
| | 16 | 87 | | queryMapping.Add(i, new KeyValuePair<string, Type>(parameterName, mpd.Type)); |
| | 16 | 88 | | alreadyGotVars.Add(parameterName, 0); |
| | 16 | 89 | | neededQueryVars.Remove(queryVar); |
| | | 90 | | } |
| | | 91 | | } |
| | | 92 | | } |
| | | 93 | | |
| | 326 | 94 | | if (neededPathVars.Count != 0) |
| | | 95 | | { |
| | 0 | 96 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format( |
| | 0 | 97 | | SR.Format(SR.UriTemplateMissingVar, XmlConvert.DecodeName(operationDescription.Name), contractName, |
| | | 98 | | } |
| | | 99 | | |
| | 326 | 100 | | if (neededQueryVars.Count != 0) |
| | | 101 | | { |
| | 0 | 102 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format |
| | 0 | 103 | | (SR.Format(SR.UriTemplateMissingVar, XmlConvert.DecodeName(operationDescription.Name), contractName, |
| | | 104 | | } |
| | 326 | 105 | | } |
| | | 106 | | |
| | | 107 | | private static string MakeDefaultGetUTString(OperationDescription od) |
| | | 108 | | { |
| | 0 | 109 | | StringBuilder sb = new StringBuilder(XmlConvert.DecodeName(od.Name)); |
| | | 110 | | //sb.Append("/*"); // note: not + "/*", see 8988 and 9653 |
| | 0 | 111 | | if (!WebHttpBehavior.IsUntypedMessage(od.Messages[0])) |
| | | 112 | | { |
| | 0 | 113 | | sb.Append("?"); |
| | 0 | 114 | | foreach (MessagePartDescription mpd in od.Messages[0].Body.Parts) |
| | | 115 | | { |
| | 0 | 116 | | string parameterName = XmlConvert.DecodeName(mpd.Name); |
| | 0 | 117 | | sb.Append(parameterName); |
| | 0 | 118 | | sb.Append("={"); |
| | 0 | 119 | | sb.Append(parameterName); |
| | 0 | 120 | | sb.Append("}&"); |
| | | 121 | | } |
| | 0 | 122 | | sb.Remove(sb.Length - 1, 1); |
| | | 123 | | } |
| | | 124 | | |
| | 0 | 125 | | return sb.ToString(); |
| | | 126 | | } |
| | | 127 | | } |
| | | 128 | | } |