Skip to content

Several OpenAPI model types in **Microsoft.OpenApi** expose a Content property with the same shape: #2677

@mdaneri

Description

@mdaneri

Summary

Several OpenAPI model types in Microsoft.OpenApi expose a Content property with the same shape:

public IDictionary<string, IOpenApiMediaType>? Content { get; set; }

This property appears in multiple classes (e.g. IOpenApiResponse, IOpenApiRequestBody, IOpenApiParameter), but there is no shared interface or abstraction that represents this common capability.

Introducing a small, focused interface for objects that expose Content would significantly improve code reuse, extensibility, and API ergonomics for SDK consumers.


Current Situation

Today, the following interfaces define a Content property independently:

  • IOpenApiResponse
  • IOpenApiRequestBody
  • IOpenApiParameter

Each defines the same member:

IDictionary<string, IOpenApiMediaType>? Content { get; set; }

However, there is no common interface that unifies them.

As a result:

  • Shared logic that operates on Content cannot be written generically
  • Consumers must duplicate code or rely on switch / if type checks
  • Generic helpers, validators, serializers, and transformers are harder to implement
  • The model does not fully reflect the structural commonality present in the OpenAPI specification

Motivation & Use Cases

This limitation becomes particularly visible when building:

  • OpenAPI document generators
  • Validation pipelines
  • Middleware or tooling that normalizes or rewrites media types
  • Shared helpers for adding/removing media types, schemas, or examples

All of these scenarios would benefit from a single abstraction representing “an OpenAPI object that has Content”.


Proposed Solution

Introduce a new interface, for example:

public interface IOpenApiContentContainer
{
    IDictionary<string, IOpenApiMediaType>? Content { get; set; }
}

Then update existing interfaces to inherit from it:

public interface IOpenApiResponse : IOpenApiExtensible, IOpenApiContentContainer
{
    string? Summary { get; set; }
    string? Description { get; set; }
    IDictionary<string, IOpenApiHeader>? Headers { get; set; }
}

public interface IOpenApiRequestBody : IOpenApiExtensible, IOpenApiContentContainer
{
    string? Description { get; set; }
    bool Required { get; set; }
}

public interface IOpenApiParameter : IOpenApiExtensible, IOpenApiContentContainer
{
    string Name { get; set; }
    ParameterLocation In { get; set; }
    bool Required { get; set; }
}

The interface name is illustrative; alternatives such as IOpenApiHasContent or IOpenApiContentAware would also be reasonable.


Benefits

  • Enables shared, strongly-typed helper methods
  • Reduces code duplication for SDK consumers
  • Improves discoverability and API consistency
  • Better reflects the OpenAPI specification’s shared concepts
  • Non-breaking if introduced via interface inheritance

Backward Compatibility

This change can be implemented in a non-breaking way by:

  • Introducing the new interface
  • Updating existing interfaces to inherit from it
  • Making no behavioral or serialization changes

Existing consumer code would continue to work unchanged.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions