You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core 2.0如何为自定义Accept头配置内置XML/JSON格式化器

Solution for HATEOAS via Custom Accept Headers in .NET Core 2 Web API

Great question! To let clients request HATEOAS links using custom Accept headers like application/json+hateoas or application/xml+hateoas, we need to extend the default formatters and add conditional logic in controllers. Here's a step-by-step implementation:

Step 1: Configure Custom Media Types in ConfigureServices

First, we'll register the custom media types with the existing JSON and XML formatters so the API recognizes them. Update your AddMvc configuration like this:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        // Map custom formats to their respective media types
        options.FormatterMappings.SetMediaTypeMappingForFormat(
            "json+hateoas", MediaTypeHeaderValue.Parse("application/json+hateoas"));
        options.FormatterMappings.SetMediaTypeMappingForFormat(
            "xml+hateoas", MediaTypeHeaderValue.Parse("application/xml+hateoas"));

        // Add custom media type to the default JSON formatter
        var jsonFormatter = options.OutputFormatters.OfType<JsonOutputFormatter>().First();
        jsonFormatter.SupportedMediaTypes.Add(
            MediaTypeHeaderValue.Parse("application/json+hateoas"));

        // Add custom media type to the default XML formatter
        var xmlFormatter = options.OutputFormatters.OfType<XmlDataContractSerializerOutputFormatter>().First();
        xmlFormatter.SupportedMediaTypes.Add(
            MediaTypeHeaderValue.Parse("application/xml+hateoas"));
    });
}

Step 2: Add Conditional HATEOAS Logic in Controllers

Create a helper method to check if the client requested HATEOAS, then modify your response to include links when needed:

private bool ShouldIncludeHateoas(HttpRequest request)
{
    var acceptHeader = request.Headers["Accept"].ToString();
    return acceptHeader.Contains("application/json+hateoas") 
           || acceptHeader.Contains("application/xml+hateoas");
}

[HttpGet("{id}")]
public IActionResult Get(int id)
{
    // Fetch your resource (example: a User object)
    var user = _userService.GetById(id);

    if (ShouldIncludeHateoas(Request))
    {
        // Add HATEOAS navigation links
        user.Links = new List<Link>
        {
            new Link
            {
                Rel = "self",
                Href = Url.Action("Get", new { id = user.Id }),
                Method = "GET"
            },
            new Link
            {
                Rel = "delete",
                Href = Url.Action("Delete", new { id = user.Id }),
                Method = "DELETE"
            }
        };
    }

    return Ok(user);
}

Make sure you have a simple Link class to represent navigation links, and update your resource class to include a nullable Links property:

public class Link
{
    public string Rel { get; set; } // Relationship name (e.g., "self", "update")
    public string Href { get; set; } // URL to the related resource
    public string Method { get; set; } // HTTP method for the link
}

// Example resource class with optional Links property
public class User
{
    public int Id { get; set; }
    public string Username { get; set; }
    public string Email { get; set; }
    public List<Link> Links { get; set; } // Will be null if HATEOAS isn't requested
}

Key Notes

  • The custom media types reuse the default formatters, so serialization/deserialization works exactly like standard JSON/XML—only the links are added conditionally.
  • For XML serialization, add [DataContract] and [DataMember] attributes to your Link and resource classes if you haven't already, to ensure proper XML output.
  • The Links property will be omitted from responses when HATEOAS isn't requested (since it's null), keeping your standard responses clean.

内容的提问来源于stack exchange,提问作者Daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:21:43