Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Collections.Generic;

namespace Microsoft.OpenApi;

/// <summary>
/// Describes an element that has content.
/// </summary>
public interface IOpenApiContentElement
{
/// <summary>
/// A map containing descriptions of potential payloads.
/// The key is a media type or media type range and the value describes it.
/// </summary>
IDictionary<string, IOpenApiMediaType>? Content { get; set; }
}

/// <summary>
/// Describes an element that has content.
/// </summary>
public interface IOpenApiReadOnlyContentElement
{
/// <summary>
/// A map containing descriptions of potential payloads.
/// The key is a media type or media type range and the value describes it.
/// </summary>
IDictionary<string, IOpenApiMediaType>? Content { get; }
}
7 changes: 1 addition & 6 deletions src/Microsoft.OpenApi/Models/Interfaces/IOpenApiHeader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Microsoft.OpenApi;
/// Defines the base properties for the headers object.
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
/// </summary>
public interface IOpenApiHeader : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiHeader>, IOpenApiReferenceable
public interface IOpenApiHeader : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiHeader>, IOpenApiReferenceable, IOpenApiReadOnlyContentElement
{
/// <summary>
/// Determines whether this header is mandatory.
Expand Down Expand Up @@ -58,9 +58,4 @@ public interface IOpenApiHeader : IOpenApiDescribedElement, IOpenApiReadOnlyExte
/// </summary>
public IDictionary<string, IOpenApiExample>? Examples { get; }

/// <summary>
/// A map containing the representations for the header.
/// </summary>
public IDictionary<string, IOpenApiMediaType>? Content { get; }

}
13 changes: 1 addition & 12 deletions src/Microsoft.OpenApi/Models/Interfaces/IOpenApiParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Microsoft.OpenApi;
/// Defines the base properties for the parameter object.
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
/// </summary>
public interface IOpenApiParameter : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiParameter>, IOpenApiReferenceable
public interface IOpenApiParameter : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiParameter>, IOpenApiReferenceable, IOpenApiReadOnlyContentElement
{
/// <summary>
/// REQUIRED. The name of the parameter. Parameter names are case sensitive.
Expand Down Expand Up @@ -93,15 +93,4 @@ public interface IOpenApiParameter : IOpenApiDescribedElement, IOpenApiReadOnlyE
/// Assign <see cref="JsonNullSentinel.JsonNull"/> to use get null as a serialized value.
/// </summary>
public JsonNode? Example { get; }

/// <summary>
/// A map containing the representations for the parameter.
/// The key is the media type and the value describes it.
/// The map MUST only contain one entry.
/// For more complex scenarios, the content property can define the media type and schema of the parameter.
/// A parameter MUST contain either a schema property, or a content property, but not both.
/// When example or examples are provided in conjunction with the schema object,
/// the example MUST follow the prescribed serialization strategy for the parameter.
/// </summary>
public IDictionary<string, IOpenApiMediaType>? Content { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,13 @@ namespace Microsoft.OpenApi;
/// Defines the base properties for the request body object.
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
/// </summary>
public interface IOpenApiRequestBody : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiRequestBody>, IOpenApiReferenceable
public interface IOpenApiRequestBody : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiRequestBody>, IOpenApiReferenceable, IOpenApiReadOnlyContentElement
{
/// <summary>
/// Determines if the request body is required in the request. Defaults to false.
/// </summary>
public bool Required { get; }

/// <summary>
/// REQUIRED. The content of the request body. The key is a media type or media type range and the value describes it.
/// For requests that match multiple keys, only the most specific key is applicable. e.g. text/plain overrides text/*
/// </summary>
public IDictionary<string, IOpenApiMediaType>? Content { get; }
/// <summary>
/// Converts the request body to a body parameter in preparation for a v2 serialization.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,13 @@ namespace Microsoft.OpenApi;
/// Defines the base properties for the response object.
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
/// </summary>
public interface IOpenApiResponse : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiResponse>, IOpenApiReferenceable, IOpenApiSummarizedElement
public interface IOpenApiResponse : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiResponse>, IOpenApiReferenceable, IOpenApiSummarizedElement, IOpenApiReadOnlyContentElement
{
/// <summary>
/// Maps a header name to its definition.
/// </summary>
public IDictionary<string, IOpenApiHeader>? Headers { get; }

/// <summary>
/// A map containing descriptions of potential response payloads.
/// The key is a media type or media type range and the value describes it.
/// </summary>
public IDictionary<string, IOpenApiMediaType>? Content { get; }

/// <summary>
/// A map of operations links that can be followed from the response.
/// The key of the map is a short name for the link,
Expand Down
7 changes: 4 additions & 3 deletions src/Microsoft.OpenApi/Models/OpenApiHeader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Microsoft.OpenApi
/// Header Object.
/// The Header Object follows the structure of the Parameter Object.
/// </summary>
public class OpenApiHeader : IOpenApiHeader, IOpenApiExtensible
public class OpenApiHeader : IOpenApiHeader, IOpenApiExtensible, IOpenApiContentElement
{
/// <inheritdoc/>
public string? Description { get; set; }
Expand Down Expand Up @@ -98,7 +98,7 @@ public virtual void SerializeAsV3(IOpenApiWriter writer)
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
}

internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version,
internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version,
Action<IOpenApiWriter, IOpenApiSerializable> callback)
{
Utils.CheckArgumentNull(writer);
Expand Down Expand Up @@ -175,7 +175,8 @@ public virtual void SerializeAsV2(IOpenApiWriter writer)
writer.WriteProperty(OpenApiConstants.AllowReserved, AllowReserved, false);

// schema
var targetSchema = Schema switch {
var targetSchema = Schema switch
{
OpenApiSchemaReference schemaReference => schemaReference.RecursiveTarget,
OpenApiSchema schema => schema,
_ => null,
Expand Down
21 changes: 15 additions & 6 deletions src/Microsoft.OpenApi/Models/OpenApiParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Microsoft.OpenApi
/// <summary>
/// Parameter Object.
/// </summary>
public class OpenApiParameter : IOpenApiExtensible, IOpenApiParameter
public class OpenApiParameter : IOpenApiExtensible, IOpenApiParameter, IOpenApiContentElement
{
private bool? _explode;
private ParameterStyle? _style;
Expand Down Expand Up @@ -60,7 +60,15 @@ public bool Explode
/// <inheritdoc/>
public JsonNode? Example { get; set; }

/// <inheritdoc/>
/// <summary>
/// A map containing the representations for the parameter.
/// The key is the media type and the value describes it.
/// The map MUST only contain one entry.
/// For more complex scenarios, the content property can define the media type and schema of the parameter.
/// A parameter MUST contain either a schema property, or a content property, but not both.
/// When example or examples are provided in conjunction with the schema object,
/// the example MUST follow the prescribed serialization strategy for the parameter.
/// </summary>
public IDictionary<string, IOpenApiMediaType>? Content { get; set; }

/// <inheritdoc/>
Expand Down Expand Up @@ -111,11 +119,11 @@ public virtual void SerializeAsV3(IOpenApiWriter writer)
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
}

internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version,
internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version,
Action<IOpenApiWriter, IOpenApiSerializable> callback)
{
Utils.CheckArgumentNull(writer);

// Validate that Cookie style is only used in OpenAPI 3.2 and later
if (Style == ParameterStyle.Cookie && version < OpenApiSpecVersion.OpenApi3_2)
{
Expand Down Expand Up @@ -226,7 +234,8 @@ internal virtual void WriteRequestBodySchemaForV2(IOpenApiWriter writer, Diction
// uniqueItems
// enum
// multipleOf
var targetSchema = Schema switch {
var targetSchema = Schema switch
{
OpenApiSchemaReference schemaReference => schemaReference.RecursiveTarget,
OpenApiSchema schema => schema,
_ => null,
Expand Down Expand Up @@ -271,7 +280,7 @@ internal virtual void WriteRequestBodySchemaForV2(IOpenApiWriter writer, Diction
public virtual void SerializeAsV2(IOpenApiWriter writer)
{
Utils.CheckArgumentNull(writer);

// Validate that Cookie style is only used in OpenAPI 3.2 and later
if (Style == ParameterStyle.Cookie)
{
Expand Down
19 changes: 11 additions & 8 deletions src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,18 @@ namespace Microsoft.OpenApi
/// <summary>
/// Request Body Object
/// </summary>
public class OpenApiRequestBody : IOpenApiExtensible, IOpenApiRequestBody
public class OpenApiRequestBody : IOpenApiExtensible, IOpenApiRequestBody, IOpenApiContentElement
{
/// <inheritdoc />
public string? Description { get; set; }

/// <inheritdoc />
public bool Required { get; set; }

/// <inheritdoc />
/// <summary>
/// REQUIRED. The content of the request body. The key is a media type or media type range and the value describes it.
/// For requests that match multiple keys, only the most specific key is applicable. e.g. text/plain overrides text/*
/// </summary>
public IDictionary<string, IOpenApiMediaType>? Content { get; set; }

/// <inheritdoc />
Expand Down Expand Up @@ -64,7 +67,7 @@ public virtual void SerializeAsV3(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
}

internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version,
Action<IOpenApiWriter, IOpenApiSerializable> callback)
{
Expand Down Expand Up @@ -110,7 +113,7 @@ public IOpenApiParameter ConvertToBodyParameter(IOpenApiWriter writer)
Extensions = Extensions?.ToDictionary(static k => k.Key, static v => v.Value)
};
// Clone extensions so we can remove the x-bodyName extensions from the output V2 model.
if (bodyParameter.Extensions is not null &&
if (bodyParameter.Extensions is not null &&
bodyParameter.Extensions.TryGetValue(OpenApiConstants.BodyName, out var bodyNameExtension) &&
bodyNameExtension is JsonNodeExtension bodyName)
{
Expand All @@ -126,7 +129,7 @@ public IEnumerable<IOpenApiParameter> ConvertToFormDataParameters(IOpenApiWriter
if (Content == null || !Content.Any())
yield break;
var properties = Content.First().Value.Schema?.Properties;
if(properties != null)
if (properties != null)
{
foreach (var property in properties)
{
Expand All @@ -144,11 +147,11 @@ public IEnumerable<IOpenApiParameter> ConvertToFormDataParameters(IOpenApiWriter
OpenApiSchemaReference => throw new InvalidOperationException("Unresolved reference target"),
_ => throw new InvalidOperationException("Unexpected schema type")
};

updatedSchema.Type = "file".ToJsonSchemaType();
updatedSchema.Format = null;
paramSchema = updatedSchema;

}
yield return new OpenApiFormDataParameter()
{
Expand All @@ -159,7 +162,7 @@ public IEnumerable<IOpenApiParameter> ConvertToFormDataParameters(IOpenApiWriter
Required = Content.First().Value.Schema?.Required?.Contains(property.Key) ?? false
};
}
}
}
}

/// <inheritdoc/>
Expand Down
6 changes: 3 additions & 3 deletions src/Microsoft.OpenApi/Models/OpenApiResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Microsoft.OpenApi
/// <summary>
/// Response object.
/// </summary>
public class OpenApiResponse : IOpenApiExtensible, IOpenApiResponse
public class OpenApiResponse : IOpenApiExtensible, IOpenApiResponse, IOpenApiContentElement
{
/// <inheritdoc/>
public string? Summary { get; set; }
Expand Down Expand Up @@ -73,7 +73,7 @@ public virtual void SerializeAsV3(IOpenApiWriter writer)
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
}

private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version,
private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version,
Action<IOpenApiWriter, IOpenApiSerializable> callback)
{
Utils.CheckArgumentNull(writer);
Expand Down Expand Up @@ -177,7 +177,7 @@ public virtual void SerializeAsV2(IOpenApiWriter writer)
// so remove it from the cloned collection so we don't write it again.
extensionsClone?.Remove(key);
}
}
}
}
}

Expand Down
Loading