限制ASP.NET Core Controller操作中接受的媒体类型 [英] Restrict accepted Media Types in ASP.NET Core Controller action

查看:171
本文介绍了限制ASP.NET Core Controller操作中接受的媒体类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ASP.NET Core Service,它可以生成JSON和XML响应.但是,我只想限制一个动作接受的媒体类型,因此Swagger只能将application/json列为有效的响应内容类型.如何在ASP.Net Core中实现这一目标?

I have an ASP.NET Core Service that produces both JSON and XML responses. However, I like to restrict the accepted Media Type for only one action, so Swagger can only list application/json as a valid response content type. How can I achieve this in ASP.Net Core?

请考虑我使用的是ASP.Net Core(ASP.NET MVC 6),而不是ASP.NET WebAPI.

Please, consider I am using ASP.Net Core (ASP.NET MVC 6), not ASP.NET WebAPI.

更新

好的,所以我将答案添加为同一问题的一部分.感谢@Helen,我能够在ASP.Net Core(ASP.Net MVC 6)中添加所需的类来实现此目的.答案基于此答案,但已修改为使用ASP.NET Core类.

Ok, so I'll add the answer as part of the same question. Thanks to @Helen, I was able to add the required classes to achieve this in ASP.Net Core (ASP.Net MVC 6). The answer is based on this answer but modified to use ASP.NET Core classes.

第1步. 创建自定义操作过滤器属性,以便管道对禁止的内容类型做出反应:

Step 1. Create a custom action filter attribute so the pipeline reacts to a forbiden content type:

/// <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可以反映限制

Step 2. Create a Swagger Operation Filter so the UI can reflect the restriction

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步. 在Startup.cs中的ConfigureServices方法内配置Swagger UI服务,以便它可以使用新创建的Operation Filter.

Step 3. Configure Swagger UI service in Startup.cs, inside the method ConfigureServices, so it can use the newly created Operation Filter.

    // 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步 .注释动作

Step 4. Annotate the action

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

推荐答案

您可以使用注释消费和生产.这些也被Swashbuckle捡起. 像这样:

You can use the annotations Consumes and Produces. These are also picked up by Swashbuckle. Like so:

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

这篇关于限制ASP.NET Core Controller操作中接受的媒体类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆