繁体   English   中英

如何从ASP.NET Core MVC响应的Content-Type中删除字符集?

[英]How do I remove the charset from Content-Type in a ASP.NET Core MVC response?

无论我尝试什么,我似乎都无法删除; charset=utf-8 来自我的响应的Content-Type标头的; charset=utf-8部分。

[HttpGet("~/appid")]
// Doesn't work
//[Produces("application/fido.trusted-apps+json")]
public string GetAppId()
{
    // Doesn't work
    Response.ContentType = "application/fido.trusted-apps+json";

    // Doesn't work
    //Response.ContentType = null;
    //Response.Headers.Add("Content-Type", "application/fido.trusted-apps+json");

    return JsonConvert.SerializeObject(new
    {
        foo = true
    });
}

我总是得到application/fido.trusted-apps+json; charset=utf-8 当我只想要application/fido.trusted-apps+json时, application/fido.trusted-apps+json; charset=utf-8

注意:这符合U2F的FIDO AppID和Facet规范v1.0的规定:

响应必须将MIME内容类型设置为“ application / fido.trusted-apps + json”。

我采用以下方法,使用中间件替换输出头。 看起来有点黑,必须使用这样的中间件:

中间件

public class AdjustHeadersMiddleware
{
    private readonly RequestDelegate _next;

    public AdjustHeadersMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext httpContext, CurrentContext currentContext)
    {
        httpContext.Response.OnStarting((state) =>
        {
            if(httpContext.Response.Headers.Count > 0 && httpContext.Response.Headers.ContainsKey("Content-Type"))
            {
                var contentType = httpContext.Response.Headers["Content-Type"].ToString();
                if(contentType.StartsWith("application/fido.trusted-apps+json"))
                {
                    httpContext.Response.Headers.Remove("Content-Type");
                    httpContext.Response.Headers.Append("Content-Type", "application/fido.trusted-apps+json");
                }
            }

            return Task.FromResult(0);
        }, null);


        await _next.Invoke(httpContext);
    }
}

Startup.cs Configure()

app.UseMiddleware<AdjustHeadersMiddleware>();

如果请求您的MVC端点的系统发送了正确的Accept: application/fido.trusted-apps+json ,那么我相信您正在寻找自定义格式器。

看到:

看起来像这样(从第二个链接借来的):

public class FidoTrustedAppOutputFormatter : IOutputFormatter 
{

    public FidoTrustedAppOutputFormatter 
    {
        SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/fido.trusted-apps+json"));
    }

    public bool CanWriteResult(OutputFormatterCanWriteContext context) 
    { 
        if (context == null) throw new ArgumentNullException(nameof(context)); 
        if (context.ContentType == null || context.ContentType.ToString() == "application/fido.trusted-apps+json") 
            return true;

        return false; 
    } 

    public async Task WriteAsync(OutputFormatterWriteContext context) 
    { 
        if (context == null) throw new ArgumentNullException(nameof(context)); 
        var response = context.HttpContext.Response; response.ContentType = "application/fido.trusted-apps+json"; 

        using (var writer = context.WriterFactory(response.Body, Encoding.UTF8)) 
        { 
            // replace with Json.net implementation
            Jil.JSON.Serialize(context.Object, writer); 
            await writer.FlushAsync(); 
        }
    }

}

public class FidoTrustedAppInputFormatter : IInputFormatter 
{

    public FidoTrustedAppInputFormatter 
    {
        SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/fido.trusted-apps+json"));
    }

    public bool CanRead(OutputFormatterCanWriteContext context) 
    { 
        if (context == null) throw new ArgumentNullException(nameof(context)); 
        if (context.ContentType == null || context.ContentType.ToString() == "application/fido.trusted-apps+json") 
            return true;

        return false; 
    } 

    public Task<InputFormatterResult> ReadAsync(InputFormatterContext context) 
    { 
        if (context == null) throw new ArgumentNullException(nameof(context)); 

        var request = context.HttpContext.Request; if (request.ContentLength == 0) 
        { 
            if (context.ModelType.GetTypeInfo().IsValueType) 
                return InputFormatterResult.SuccessAsync(Activator.CreateInstance(context.ModelType)); 
            else return InputFormatterResult.SuccessAsync(null); 
        } 

        var encoding = Encoding.UTF8;//do we need to get this from the request im not sure yet 

        using (var reader = new StreamReader(context.HttpContext.Request.Body)) 
        { 
            var model = Jil.JSON.Deserialize(reader, context.ModelType); 
            return InputFormatterResult.SuccessAsync(model); 
        } 
    } 

}

然后在您的启动中注册它:

services.AddMvcCore(options =>  
{ 
    options.InputFormatters.Insert(0, new FidoTrustedAppInputFormatter ());
    options.OutputFormatters.Insert(0, new FidoTrustedAppOutputFormatter ()); 
});

我发现您可以使用ContentResult在控制器中覆盖它。 因此,您可以通过执行以下示例来实现所需的功能

string bodyJson = JsonConvert.SerializeObject(new
{
    foo = true
})

var response = new ContentResult()
{
    Content = bodyJson,
    ContentType = "application/fido.trusted-apps+json",
    StatusCode = (int)System.Net.HttpStatusCode.OK,
};

return response;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM