/// <summary>
        /// Add Serialization services
        /// </summary>
        /// <param name="services">ServicesCollection</param>
        /// <param name="builderAction">Action to handle the serialization builder</param>
        /// <returns>ServicesCollection</returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static SerializationBuilder AddSerialization(
            this IServiceCollection services,
            Action <SerializationBuilder> builderAction)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }
            if (builderAction == null)
            {
                throw new ArgumentNullException(nameof(builderAction));
            }

            var builder = new SerializationBuilder(services);

            builderAction.Invoke(builder);
            builder.Build();

            return(builder);
        }
Beispiel #2
0
        private RestClientMethod BuildMethod(Operation operation, HttpRequest httpRequest, ICollection <RequestParameter> requestParameters, ResponseHeaderGroupType?responseHeaderModel)
        {
            HttpWithBodyRequest?httpRequestWithBody         = httpRequest as HttpWithBodyRequest;
            Dictionary <string, PathSegment> uriParameters  = new Dictionary <string, PathSegment>();
            Dictionary <string, PathSegment> pathParameters = new Dictionary <string, PathSegment>();
            List <QueryParameter>            query          = new List <QueryParameter>();
            List <RequestHeader>             headers        = new List <RequestHeader>();
            Dictionary <RequestParameter, ReferenceOrConstant> allParameters    = new Dictionary <RequestParameter, ReferenceOrConstant>();
            Dictionary <RequestParameter, Parameter>           methodParameters = new Dictionary <RequestParameter, Parameter>();

            RequestBody?body = null;

            (RequestParameter, ReferenceOrConstant)? bodyParameter = null;
            RequestParameter[] parameters = operation.Parameters.Concat(requestParameters).ToArray();
            foreach (RequestParameter requestParameter in parameters)
            {
                string defaultName    = requestParameter.Language.Default.Name;
                string serializedName = requestParameter.Language.Default.SerializedName ?? defaultName;
                ReferenceOrConstant constantOrReference;
                Schema valueSchema = requestParameter.Schema;

                if (requestParameter.Implementation == ImplementationLocation.Method)
                {
                    Parameter?parameter = null;
                    // TODO: always generate virtual parameters
                    if (!(requestParameter is VirtualParameter) &&
                        requestParameter.Schema is ConstantSchema constant)
                    {
                        constantOrReference = ParseConstant(constant);
                        valueSchema         = constant.ValueType;
                    }
                    else
                    {
                        parameter = BuildParameter(requestParameter);

                        if (requestParameter.GroupedBy is RequestParameter groupedByParameter)
                        {
                            var groupModel = (ObjectType)_context.TypeFactory.CreateType(groupedByParameter.Schema, false).Implementation;
                            var property   = groupModel.GetPropertyForGroupedParameter(requestParameter);

                            constantOrReference = new Reference($"{groupedByParameter.CSharpName()}.{property.Declaration.Name}", property.Declaration.Type);
                        }
                        else
                        {
                            constantOrReference = parameter;
                        }
                    }

                    allParameters.Add(requestParameter, constantOrReference);

                    if (parameter != null &&
                        requestParameter.Flattened != true &&
                        requestParameter.GroupedBy == null)
                    {
                        methodParameters.Add(requestParameter, parameter);
                    }
                }
                else
                {
                    constantOrReference = _parameters[requestParameter.Language.Default.Name];
                }

                if (requestParameter.Protocol.Http is HttpParameter httpParameter)
                {
                    SerializationFormat serializationFormat = BuilderHelpers.GetSerializationFormat(valueSchema);
                    bool skipEncoding = requestParameter.Extensions !.TryGetValue("x-ms-skip-url-encoding", out var value) && Convert.ToBoolean(value);
                    switch (httpParameter.In)
                    {
                    case ParameterLocation.Header:
                        headers.Add(new RequestHeader(serializedName, constantOrReference, GetSerializationStyle(httpParameter, valueSchema), serializationFormat));
                        break;

                    case ParameterLocation.Query:
                        query.Add(new QueryParameter(serializedName, constantOrReference, GetSerializationStyle(httpParameter, valueSchema), !skipEncoding, serializationFormat));
                        break;

                    case ParameterLocation.Path:
                        pathParameters.Add(serializedName, new PathSegment(constantOrReference, !skipEncoding, serializationFormat));
                        break;

                    case ParameterLocation.Body:
                        bodyParameter = (requestParameter, constantOrReference);
                        break;

                    case ParameterLocation.Uri:
                        uriParameters.Add(serializedName, new PathSegment(constantOrReference, !skipEncoding, serializationFormat, isRaw: true));
                        break;
                    }
                }
            }

            if (bodyParameter is var(bodyRequestParameter, bodyParameterValue))
            {
                Debug.Assert(httpRequestWithBody != null);
                if (httpRequestWithBody.KnownMediaType == KnownMediaType.Binary)
                {
                    body = new BinaryRequestBody(bodyParameterValue);
                }
                else if (httpRequestWithBody.KnownMediaType == KnownMediaType.Text)
                {
                    body = new TextRequestBody(bodyParameterValue);
                }
                else
                {
                    var serialization = _serializationBuilder.Build(
                        httpRequestWithBody.KnownMediaType,
                        bodyRequestParameter.Schema,
                        bodyParameterValue.Type);

                    // This method has a flattened body
                    if (bodyRequestParameter.Flattened == true)
                    {
                        var objectType        = (ObjectType)_context.Library.FindTypeForSchema(bodyRequestParameter.Schema);
                        var virtualParameters = requestParameters.OfType <VirtualParameter>().ToArray();

                        List <ObjectPropertyInitializer> initializationMap = new List <ObjectPropertyInitializer>();
                        foreach (var virtualParameter in virtualParameters)
                        {
                            var actualParameter = allParameters[virtualParameter];

                            initializationMap.Add(new ObjectPropertyInitializer(
                                                      objectType.GetPropertyForSchemaProperty(virtualParameter.TargetProperty, true),
                                                      actualParameter));
                        }

                        body = new FlattenedSchemaRequestBody(objectType, initializationMap.ToArray(), serialization);
                    }
                    else
                    {
                        body = new SchemaRequestBody(bodyParameterValue, serialization);
                    }
                }
            }

            PathSegment[] pathSegments = GetPathSegments(httpRequest.Uri, uriParameters, isRaw: true)
                                         .Concat(GetPathSegments(httpRequest.Path, pathParameters))
                                         .ToArray();
            Request request = new Request(
                httpRequest.Method.ToCoreRequestMethod() ?? RequestMethod.Get,
                pathSegments,
                query.ToArray(),
                headers.ToArray(),
                body
                );

            string operationName = operation.CSharpName();

            List <Response> clientResponse = new List <Response>();

            if (operation.IsLongRunning)
            {
                // Ignore response body and headers for LROs as the ArmOperationHelpers figures out them dynamically
                responseHeaderModel = null;
            }

            foreach (var response in operation.Responses)
            {
                clientResponse.Add(new Response(
                                       operation.IsLongRunning ? null : BuildResponseBody(response),
                                       response.HttpResponse.IntStatusCodes.ToArray()
                                       ));
            }

            var responseType = ReduceResponses(clientResponse);

            return(new RestClientMethod(
                       operationName,
                       BuilderHelpers.EscapeXmlDescription(operation.Language.Default.Description),
                       responseType,
                       request,
                       OrderParameters(methodParameters.Values),
                       clientResponse.ToArray(),
                       responseHeaderModel
                       ));
        }