在ASP MVC Web API中,手动MediaTypeFormatter管理的最佳实践是什么

本文关键字:管理 最佳 是什么 MediaTypeFormatter 手动 MVC ASP Web API | 更新日期: 2023-09-27 18:22:16

我有ASP MVC Web API服务,我的方法应该以特定格式(JSON、XML等)返回数据。响应格式取决于方法,而不取决于客户端偏好。

我使用HttpResponseMessageObjectContent,需要为ObjectContent设置MediaTypeFormatter。

我可以这样做:

new ObjectContent<MyDataContract>(data, new JsonMediaTypeFormatter())

或者这样:

new ObjectContent<MyDataContract>(
    data, 
    Configuration.Formatters
        .FirstOrDefault(f => f.GetType() == typeof(JsonMediaTypeFormatter))
)

没有一个看起来特别好看。第一个为每个请求创建一个新对象。第二个使用了搜索/过滤器,在这里看起来不合适。

对于我的问题,什么是更好的解决方案?

在ASP MVC Web API中,手动MediaTypeFormatter管理的最佳实践是什么

您可以在webApiConfig文件中进行设置。

  config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

此外,还可以在返回数据时为响应设置MediaType-

     [HttpGet]
      public HttpResponseMessage GetJson()
      {
        var result = new List<string>();
        for (int i = 0; i < 50; i++)
            result.Add("Hello World");
       return Request.CreateResponse(HttpStatusCode.OK, result, new 
        MediaTypeHeaderValue("application/json"));
    }

在每次操作的基础上完全控制返回格式的最简单方法就是利用IActionResult实现。

使用JsonResult始终使用默认配置的任何序列化程序返回json格式的输出。

  • JsonResult类
  • JsonResult类遗留MVC版本
return new JsonResult(data);

使用XML的自定义IActionResult实现或为您提供的库版本,例如:

  • Microsoft.AspNetCore.Mvc.Formatters.Xml.Extensions
  • MvcContrib(用于传统MVC)

这为您提供了可以以类似方式返回的XmlResult类型。

这些抽象背后的想法是,您不需要在控制器代码中进行手动序列化,但实现仍然会使用AspNetCore中配置的底层序列化程序强制使用特定格式,该序列化程序会跳过格式的内容协商。

为什么不使用IHttpActionResult并返回Ok()?您是否明确需要HttpResponseMessage?此外,您是否希望始终返回JSON,这取决于客户端期望的内容类型?

如果您希望始终返回JSON并在WebApiConfig文件中使用IHttpActionResult,您可以添加以下内容:

config.Formatters.Clear();
config.Formatters.Add(new JsonMediaTypeFormatter());

这样API将始终返回JSON,并且在控制器中只能返回OK:

return this.Ok(data); // will be enough, no need to specify the content type

否则,如果你坚持使用HttpResponseMessage,你可以继承ObjectContent类并使用它(代码是动态编写的,可能需要一些tweeks)

public class JsonObjectContent<T> : ObjectContent<T>
{
    public JsonObjectContent(T data) : base(data, new JsonMediaTypeFormatter())
    {
    }
}

在你的控制器中,你会说

new JsonObjectContent<MyDataContract>(data)