web-dev-qa-db-ja.com

ASP.NET Core Controllerアクションで受け入れられるメディアタイプを制限する

JSONとXMLの両方の応答を生成するASP.NETコアサービスがあります。ただし、受け入れられるメディアタイプを1つのアクションのみに制限したいので、Swaggerはapplication/jsonを有効な応答コンテンツタイプとしてのみリストできます。 ASP.Net Coreでこれを実現するにはどうすればよいですか?

ASP.NET WebAPIではなくASP.Net Core(ASP.NET MVC 6)を使用していることを考慮してください。

enter image description here

[〜#〜]更新[〜#〜]

では、同じ質問の一部として回答を追加します。 @Helenのおかげで、ASP.Net Core(ASP.Net MVC 6)でこれを実現するために必要なクラスを追加することができました。答えは この答え に基づいていますが、ASP.NET Coreクラスを使用するように変更されています。

ステップ1。カスタムアクションフィルター属性を作成して、パイプラインが禁止されたコンテンツタイプに反応するようにします。

/// <summary>
/// SwaggerResponseContentTypeAttribute
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public sealed class SwaggerResponseContentTypeAttribute : ActionFilterAttribute
{
    /// <summary>
    /// SwaggerResponseContentTypeAttribute
    /// </summary>
    /// <param name="responseType"></param>
    public SwaggerResponseContentTypeAttribute(string responseType)
    {
        ResponseType = responseType;
    }
    /// <summary>
    /// Response Content Type
    /// </summary>
    public string ResponseType { get; private set; }

    /// <summary>
    /// Remove all other Response Content Types
    /// </summary>
    public bool Exclusive { get; set; }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var accept = context.HttpContext.Request.Headers["accept"];
        var accepted = accept.ToString().ToLower().Contains(ResponseType.ToLower());
        if (!accepted)
            context.Result = new StatusCodeResult((int)HttpStatusCode.NotAcceptable); 

    }

}

ステップ2。 Swagger操作フィルターを作成して、UIが制限を反映できるようにします

public class ResponseContentTypeOperationFilter : IOperationFilter
{

    public void Apply(Swashbuckle.AspNetCore.Swagger.Operation operation, OperationFilterContext context)
    {
        var requestAttributes = context.ControllerActionDescriptor.GetControllerAndActionAttributes(true).Where(c=>c.GetType().IsAssignableFrom(typeof(SwaggerResponseContentTypeAttribute))).Select(c=> c as SwaggerResponseContentTypeAttribute).FirstOrDefault();

        if (requestAttributes != null)
        {
            if (requestAttributes.Exclusive)
                operation.Produces.Clear();

            operation.Produces.Add(requestAttributes.ResponseType);
        }
    }
}

ステップ3。メソッドConfigureServices内のStartup.csでSwagger UIサービスを設定します。新しく作成した操作フィルターを使用します。

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        services.Configure<MvcOptions>(options =>
        {
            options.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter());

        });
        // Register the Swagger generator, defining 1 or more Swagger documents
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
            c.OperationFilter<ResponseContentTypeOperationFilter>();
        });
    }

ステップ4。アクションに注釈を付ける

    // GET api/values
    [HttpGet]
    [WebService.Utils.SwaggerResponseContentType(responseType: "application/json", Exclusive = true)]
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }
7
Alfredo A.

消費と生産の注釈を使用できます。これらもスワッシュバックルで拾われます。そのようです:

[HttpGet]
[Consumes("application/xml")]
[Produces("application/xml")]
public IEnumerable<string> Get()
{
    return new string[] { "value1", "value2" };
}
8
jintux