<#@ template language="C#" inherits="BaseRequestMarshaller" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <# AddLicenseHeader(); AddCommonUsingStatements(); #> using System.Xml; namespace <#=this.Config.Namespace #>.Model.Internal.MarshallTransformations { /// /// <#=this.Operation.Name #> Request Marshaller /// public class <#=this.Operation.Name#>RequestMarshaller : IMarshallerRequest> , IMarshaller { /// /// Marshaller the request object to the HTTP request. /// /// /// public IRequest Marshall(AmazonWebServiceRequest input) { return this.Marshall((<#=this.Operation.Name#>Request)input); } /// /// Marshaller the request object to the HTTP request. /// /// /// public IRequest Marshall(<#=this.Operation.Name #>Request publicRequest) { var request = new DefaultRequest(publicRequest, "<#=this.Config.Namespace#>"); <# // Assign HttpMethod if present or default to POST if(!string.IsNullOrWhiteSpace(this.Operation.HttpMethod)){ #> request.HttpMethod = "<#=this.Operation.HttpMethod#>"; <# } var requestStructure = this.Operation.RequestStructure; var payload = this.Operation.RequestPayloadMember; var shouldMarshallPayload = (payload != null && payload.IsStructure); // This block adds members of the request object to the actual request ProcessRequestUri(this.Operation); ProcessHeaderMembers("publicRequest", this.Operation.RequestHeaderMembers); ProcessUriMembers("publicRequest", this.Operation); ProcessQueryStringMembers("publicRequest", this.Operation); #> request.ResourcePath = "<#=this.Operation.RequestUri #>"; <# // Process any members which are marshalled as part of the request body if(this.Operation.RequestHasBodyMembers || shouldMarshallPayload) { ProcessRequestBodyMembers("publicRequest", this.Operation); } #> <# // If there aren't any members that are marshalled as part of the body or streamed if(this.Operation.UseQueryString) { #> request.UseQueryString = true; <# } // We skip endpoint host prefix handling for S3 and S3 Control as it's implemented by endpoint rules. if(!string.IsNullOrEmpty(this.Operation.EndpointHostPrefix) && this.Config.ServiceId != "S3" && this.Config.ServiceId != "S3 Control") { ProcessEndpointHostPrefixMembers("publicRequest", this.Operation); } #> return request; } <# this.AddRequestSingletonMethod(); #> } } <#+ void ProcessRequestBodyMembers(string variableName, Operation operation) { var level = 0; #> var stringWriter = new XMLEncodedStringWriter(CultureInfo.InvariantCulture); using (var xmlWriter = XmlWriter.Create(stringWriter, new XmlWriterSettings() { Encoding = System.Text.Encoding.UTF8, OmitXmlDeclaration = true, NewLineHandling = NewLineHandling.Entitize })) { <#+ if(operation.RequestPayloadMember==null) { #> xmlWriter.WriteStartElement("<#=operation.Input.LocationName#>", "<#=operation.XmlNamespace#>"); <#+ } else { #> if (<#=variableName + ".IsSet" + operation.RequestPayloadMember.PropertyName#>()) { xmlWriter.WriteStartElement("<#=operation.RequestPayloadMember.MarshallName#>", "<#=operation.XmlNamespace#>"); <#+ level++; } var childmembers = operation.RequestPayloadMember == null ? operation.RequestBodyMembers : operation.RequestPayloadMember.Shape.Members; variableName = operation.RequestPayloadMember == null ? variableName : variableName + "." + operation.RequestPayloadMember.PropertyName; foreach(var member in childmembers) { if(member.IsStructure) { ProcessStructure(level, variableName, member, operation.XmlNamespace); } else if(member.IsList) { ProcessList(level, variableName, member, operation.XmlNamespace); } else if(member.IsMap) { ProcessMap(level, variableName, member, operation.XmlNamespace); } else { #> <#=new string(' ', level * 4)#> if(<#=variableName#>.IsSet<#=member.PropertyName#>()) <#=new string(' ', level * 4)#> xmlWriter.WriteElementString("<#=member.MarshallName#>", "<#=operation.XmlNamespace#>", <#=member.PrimitiveMarshaller#>(<#=variableName#>.<#=member.PropertyName#><#=(member.UseNullable ? ".Value" : string.Empty)#>)); <#+ if(member.IsIdempotent) { #> else <#=new string(' ', level * 4)#> xmlWriter.WriteElementString("<#=member.MarshallName#>", "<#=operation.XmlNamespace#>", Guid.NewGuid().ToString()); <#+ } #> <#=""#> <#+ } } #> <#=new string(' ', level * 4)#> xmlWriter.WriteEndElement(); <#+ if(operation.RequestPayloadMember!=null) { #> <#=new string(' ', level * 4)#> } <#+ level--; } #> } try { string content = stringWriter.ToString(); request.Content = System.Text.Encoding.UTF8.GetBytes(content); request.Headers["Content-Type"] = "application/xml"; <#+ GenerateRequestChecksumHandling(operation, "content"); #> request.Headers[Amazon.Util.HeaderKeys.XAmzApiVersion] = "<#=this.Config.ServiceModel.APIVersion#>"; } catch (EncoderFallbackException e) { throw new AmazonServiceException("Unable to marshall request to XML", e); } <#+ } void ProcessMembers(int level, string variableName, IEnumerable members, string xmlNamespace) { foreach(var member in members) { if(member.IsStructure) { ProcessStructure(level, variableName, member, xmlNamespace); } else if(member.IsList) { ProcessList(level, variableName, member, xmlNamespace); } else if(member.IsMap) { ProcessMap(level, variableName, member, xmlNamespace); } else { #> <#=new string(' ', level * 4)#> if(<#=variableName#>.IsSet<#=member.PropertyName#>()) <#=new string(' ', level * 4)#> xmlWriter.WriteElementString("<#=member.MarshallName#>", "<#=xmlNamespace#>", <#=member.PrimitiveMarshaller#>(<#=variableName#>.<#=member.PropertyName#><#=(member.UseNullable ? ".Value" : string.Empty)#>)); <#+ } } } void ProcessStructure(int level, string variableName, Member member, string xmlNamespace) { var shape = member.Shape.IsList ? member.Shape.ListShape : member.Shape ; variableName = member.Shape.IsList ? variableName : variableName + "." + member.PropertyName; // Use shape's ListMarshallName if the structure is a list. var marshallName = member.Shape.IsList ? member.Shape.ListMarshallName ?? "member" : member.MarshallName; #> <#=new string(' ', level * 4)#> if (<#=variableName#> != null) <#=new string(' ', level * 4)#> { <#=new string(' ', level * 4)#> xmlWriter.WriteStartElement("<#=marshallName#>", "<#=xmlNamespace#>"); <#+ ProcessMembers(level + 1, variableName, shape.Members, xmlNamespace); #> <#=new string(' ', level * 4)#> xmlWriter.WriteEndElement(); <#=new string(' ', level * 4)#> } <#+ } void ProcessList(int level, string variableName, Member member, string xmlNamespace) { var listVariable = (variableName + member.PropertyName).Replace(".",string.Empty); var listItemVariable = (variableName + member.PropertyName).Replace(".",string.Empty) + "Value"; #> <#=new string(' ', level * 4)#> var <#=listVariable#> = <#=variableName#>.<#=member.PropertyName#>; <#=new string(' ', level * 4)#> if (<#=listVariable#> != null && <#=listVariable#>.Count > 0) <#=new string(' ', level * 4)#> { <#=new string(' ', level * 4)#> xmlWriter.WriteStartElement("<#=member.MarshallName#>", "<#=xmlNamespace#>"); <#=new string(' ', level * 4)#> foreach (var <#=listItemVariable#> in <#=listVariable#>) <#=new string(' ', level * 4)#> { <#+ if(member.Shape.ListShape.IsStructure) { ProcessStructure(level + 1, listItemVariable, member, xmlNamespace); } else { var listMarshallName = member.Shape.ListMarshallName ?? "member"; if(member.Shape.ListShape.IsDateTime) { // Use shape's ListMarshallName as it's a list structure. #> <#=new string(' ', level * 4)#> xmlWriter.WriteStartElement("<#=listMarshallName#>", "<#=xmlNamespace#>"); <#=new string(' ', level * 4)#> xmlWriter.WriteValue(<#=member.Shape.ListShape.PrimitiveMarshaller(MarshallLocation.Body)#>(<#=listItemVariable#>)); <#=new string(' ', level * 4)#> xmlWriter.WriteEndElement(); <#+ } else { // Use shape's ListMarshallName as it's a list structure. #> <#=new string(' ', level * 4)#> xmlWriter.WriteStartElement("<#=listMarshallName#>", "<#=xmlNamespace#>"); <#=new string(' ', level * 4)#> xmlWriter.WriteValue(<#=listItemVariable#>); <#=new string(' ', level * 4)#> xmlWriter.WriteEndElement(); <#+ } } #> <#=new string(' ', level * 4)#> } <#=new string(' ', level * 4)#> xmlWriter.WriteEndElement(); <#=new string(' ', level * 4)#> } <#+ } void ProcessMap(int level, string variableName, Member member, string xmlNamespace) { #> <#=new string(' ', level * 4)#> xmlWriter.WriteStartElement("<#=member.MarshallName#>", "<#=xmlNamespace#>"); <#=new string(' ', level * 4)#> foreach (var kvp in <#=variableName#>.<#=member.PropertyName#>) <#=new string(' ', level * 4)#> { <#=new string(' ', level * 4)#> xmlWriter.WriteStartElement("entry", "<#=xmlNamespace#>"); <#=new string(' ', level * 4)#> xmlWriter.WriteElementString("key", "<#=xmlNamespace#>", kvp.Key); <#=new string(' ', level * 4)#> xmlWriter.WriteElementString("value", "<#=xmlNamespace#>", kvp.Value); <#=new string(' ', level * 4)#> xmlWriter.WriteEndElement(); <#=new string(' ', level * 4)#> } <#=new string(' ', level * 4)#> xmlWriter.WriteEndElement(); <#+ } #>