簡體   English   中英

ASP.NET Core 2.0-動態定義文檔模型

[英]ASP.NET Core 2.0 - Define Model For Documentation Dynamically

我們有一套REST服務。 服務在POST請求中接受json中的模型,並在POST響應中返回json中的模型。 但是,這些模型在我們的ASP.NET Core 2.0項目中不是物理編譯的類型。 相反,它們是映射到我們內部類型的映射對象。 也就是說,提供的json只是我們核心實體之上的一層,這些實體被削減以將數據暴露給第三方。

但是,實體需要使用Swagger進行記錄。 Swashbuckle在這方面做得很好。 它通過名稱空間Microsoft.AspNetCore.Mvc.ApiExplorer來實現。 我現在正在嘗試為使用此命名空間在json中提供服務的實體定義元數據。 但是,我運氣不好。 我想定義一個不基於項目中物理類型的類型。 我很高興定義名稱和屬性等,但是我所做的事情無濟於事。 例如,抽象類ModelMetadata需要一個ModelMetadataIdentity類型的參數,但是此類型在構造函數中不接受任何參數,並且所有重要屬性均為Get only。 因此,例如,我實際上無法在ModelMetadataIdentity上設置Name屬性。 我猜測這甚至是我什至可以構造ModelMetadataIdentity的代碼中的一個小故障。 我猜想該類應該是抽象的。

例如,有一個稱為ForType的靜態方法可以編譯,並且不會引發任何異常,例如:

        var customModelMetadataProvider = new CustomModelMetadataProvider(ModelMetadataIdentity.ForType(typeof(TaskInfo)));
        context.ApiDescription.SupportedResponseTypes.Add(new Microsoft.AspNetCore.Mvc.ApiExplorer.ApiResponseType { ModelMetadata = customModelMetadataProvider });

但是,這沒有任何作用。 Swagger文檔中沒有TaskInfo的文檔。 但是,更重要的是,這對我不利,因為TaskInfo是預編譯類型,並且我正在嘗試定義概念性類型,而不是物理類型。

要了解我在說什么,您可以在此處查看一個示例: https : //github.com/Microsoft/aspnet-api-versioning/tree/master/samples/webapi/SwaggerODataWebApiSample 例如,在項目中將Order和Person定義為類型,但是我想動態地為這些類型構造元數據。

如何使用Microsoft.AspNetCore.Mvc.ApiExplorer命名空間定義概念(動態)類型? 如何強制Swashbuckle識別使用此命名空間定義的元數據?

PS:我知道有些人會想:“為什么不直接用代碼編寫模型並進行編譯?”。 好吧,顯然可以做到這一點,但是這為配置REST服務增加了不必要的額外步驟。 從內部實體到外部實體的映射是通過配置完成的,而不是代碼! 配置人員不必編譯任何東西即可公開這些實體。

可以使用Swashbuckle這樣完成:

public class SwaggerOperationFilter : IOperationFilter
{
    #region Fields
    private const string testpropertyname = "TestProperty";
    private const string TestSchemaRef = "ADef";
    private static Schema TestSchema = new Schema { Required = new List<string> { testpropertyname }, Example = new { TestProperty = "Test" }, Description = "This is a Description", Title = "TestSchema", Properties = new Dictionary<string, Schema>() };
    #endregion

    #region Static Constructor
    static SwaggerOperationFilter()
    {
        TestSchema.Properties.Add(testpropertyname, new Schema { Type = "string" });
    }
    #endregion

    #region Implementation
    public void Apply(Operation operation, OperationFilterContext context)
    {
        if (!context.SchemaRegistry.Definitions.ContainsKey(TestSchemaRef))
        {
            context.SchemaRegistry.Definitions.Add(TestSchemaRef, TestSchema);
        }

        operation.Responses["200"] = new Response
        {
            Description = "This is a Response Description",
            Schema = TestSchema
        };
    }
    #endregion
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM