in src/AutoRest.CSharp/Common/Output/Models/RestClientBuilder.cs [240:360]
private static RequestBody? BuildRequestBody(IReadOnlyCollection<RequestPartSource> allParameters, BodyMediaType bodyMediaType, OutputLibrary? library, TypeFactory typeFactory)
{
RequestBody? body = null;
var references = new Dictionary<string, ReferenceOrConstant>();
var bodyParameters = new List<(InputParameter, ReferenceOrConstant)>();
foreach (var (_, inputParameter, value, _) in allParameters)
{
if (inputParameter is not null)
{
references[inputParameter.NameInRequest] = value;
}
if (inputParameter is { Location: RequestLocation.Body })
{
bodyParameters.Add((inputParameter, value));
}
}
if (bodyParameters.Count > 0)
{
if (bodyMediaType == BodyMediaType.Multipart)
{
List<MultipartRequestBodyPart> value = new List<MultipartRequestBodyPart>();
foreach (var (_, reference) in bodyParameters)
{
var type = reference.Type;
RequestBody requestBody;
if (type.Equals(typeof(string)))
{
requestBody = new TextRequestBody(reference);
}
else if (type.IsFrameworkType && type.FrameworkType == typeof(Stream))
{
requestBody = new BinaryRequestBody(reference);
}
else if (type.IsList)
{
requestBody = new BinaryCollectionRequestBody(reference);
}
else
{
throw new NotImplementedException();
}
value.Add(new MultipartRequestBodyPart(reference.Reference.Name, requestBody));
}
body = new MultipartRequestBody(value.ToArray());
}
else if (bodyMediaType == BodyMediaType.Form)
{
UrlEncodedBody urlbody = new UrlEncodedBody();
foreach (var (inputParameter, reference) in bodyParameters)
{
urlbody.Add(inputParameter.NameInRequest, reference);
}
body = urlbody;
}
else
{
Debug.Assert(bodyParameters.Count == 1);
var (bodyRequestParameter, bodyParameterValue) = bodyParameters[0];
if (bodyMediaType == BodyMediaType.Binary ||
// WORKAROUND: https://github.com/Azure/autorest.modelerfour/issues/360
bodyRequestParameter.Type is InputPrimitiveType { Kind: InputPrimitiveTypeKind.Stream })
{
body = new BinaryRequestBody(bodyParameterValue);
}
else if (bodyMediaType == BodyMediaType.Text)
{
body = new TextRequestBody(bodyParameterValue);
}
else
{
var serialization = SerializationBuilder.Build(
bodyMediaType,
bodyRequestParameter.Type,
bodyParameterValue.Type,
null);
// This method has a flattened body
if (bodyRequestParameter.Kind == InputOperationParameterKind.Flattened && library != null)
{
(InputType inputType, bool isNullable) = bodyRequestParameter.Type is InputNullableType nullableType ? (nullableType.Type, true) : (bodyRequestParameter.Type, false);
var objectType = inputType switch
{
InputModelType inputModelType => typeFactory.CreateType(inputModelType).Implementation as SerializableObjectType,
_ => null
};
if (objectType == null)
{
throw new InvalidOperationException("Unexpected flattened type");
}
var properties = objectType.EnumerateHierarchy().SelectMany(o => o.Properties).ToList();
var initializationMap = new List<ObjectPropertyInitializer>();
foreach ((_, InputParameter? inputParameter, _, _) in allParameters)
{
if (inputParameter is { FlattenedBodyProperty: { } flattenedProperty })
{
var property = properties.First(p => p.InputModelProperty?.SerializedName == flattenedProperty.SerializedName);
initializationMap.Add(new ObjectPropertyInitializer(property, references[inputParameter.NameInRequest].Reference));
}
}
body = new FlattenedSchemaRequestBody(objectType, initializationMap.ToArray(), serialization);
}
else
{
body = new SchemaRequestBody(bodyParameterValue, serialization);
}
}
}
}
return body;
}