简体   繁体   English

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

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

No matter what I try I cannot seem to remove the ; charset=utf-8 无论我尝试什么,我似乎都无法删除; charset=utf-8 ; charset=utf-8 part from my response's Content-Type header. 来自我的响应的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
    });
}

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

Note: This is to conform with the FIDO AppID and Facet Specification v1.0 for U2F which states: 注意:这符合U2F的FIDO AppID和Facet规范v1.0的规定:

The response must set a MIME Content-Type of "application/fido.trusted-apps+json". 响应必须将MIME内容类型设置为“ application / fido.trusted-apps + json”。

I went with the following approach, using middleware to replace the header on the way out. 我采用以下方法,使用中间件替换输出头。 Seems kinda hacky to have to use middleware like this: 看起来有点黑,必须使用这样的中间件:

Middleware 中间件

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() Startup.cs Configure()

app.UseMiddleware<AdjustHeadersMiddleware>();

If the system requesting your MVC endpoint sends a proper Accept: application/fido.trusted-apps+json , then I believe a custom formatter is what you're looking for. 如果请求您的MVC端点的系统发送了正确的Accept: application/fido.trusted-apps+json ,那么我相信您正在寻找自定义格式器。

See: 看到:

It would look something like this (borrowed from the second link): 看起来像这样(从第二个链接借来的):

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); 
        } 
    } 

}

Then register it in your startup: 然后在您的启动中注册它:

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

I have found that you can use ContentResult to override this in your controller. 我发现您可以使用ContentResult在控制器中覆盖它。 So you could achieve what you want by doing the following for example 因此,您可以通过执行以下示例来实现所需的功能

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.

相关问题 在ASP.NET MVC中设置空响应的Content-Type - Setting the Content-Type of an empty response in ASP.NET MVC InvalidOperationException:错误的内容类型:ASP.NET Core - InvalidOperationException: Incorrect Content-Type: ASP.NET Core ASP.NET MVC应用程序不输出内容类型标头 - ASP.NET MVC Application not outputting content-type header 从 ASP.NET Core 中的 controller 返回 Content-Type 作为 application/javascript - Returning Content-Type as application/javascript from a controller in ASP.NET Core 如何从 HttpClient.PostAsJsonAsync() 生成的 Content-Type header 中删除 charset=utf8? - How to remove charset=utf8 from Content-Type header generated by HttpClient.PostAsJsonAsync()? 如何将响应数据格式化为ASP.NET CORE? - How do I format response data into ASP.NET CORE? 如何在ASP.NET MVC 3中发送响应和文件? - How do I send a response and a file in ASP.NET MVC 3? 尝试使用Ajax将png上载到Asp.net Core服务器时出现“错误的Content-Type:image / png” - “Incorrect Content-Type: image/png” when trying to upload png with Ajax to Asp.net Core server asp.net WebApi:未能序列化内容类型“application/xml”的响应正文; 字符集=utf-8' - asp.net WebApi: failed to serialize the response body for content type 'application/xml; charset=utf-8' ASP.NET Core:在Json Response中设置与UTF-8不同的charset - ASP.NET Core: Set charset different from UTF-8 in Json Response
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM