是否可以仅将MediaTypeFormatter更改为JSON?

我有一个web api,其中全局配置配置为使用:XmlMediaTypeFormatter

我的问题是我不会使用新的控制器扩展这个web api,而是使用JsonMediaTypeFormatter。

是否可以仅为一个API控制器类将MediaTypeFormatter更改为JSON?

我的问题是没有返回JSON,我已经通过返回HttpResponseMessage来解释这个:

return new HttpResponseMessage { Content = new ObjectContent("Hello world", new JsonMediaTypeFormatter()), StatusCode = HttpStatusCode.OK }; 

这是我要求问题的要求。 如果我有一个具有两个属性的对象:

 public class VMRegistrant { public int MerchantId { get; set; } public string Email { get; set; } } 

我的控制器操作将VMRegistrant作为参数:

 public HttpResponseMessage CreateRegistrant(VMRegistrant registrant) { // Save registrant in db... } 

但问题是,当我用JSON调用该操作时,它失败了。

您可以让控制器返回IHttpActionResult并使用扩展方法HttpRequestMessageExtensions.CreateResponse并指定要使用的格式化程序:

 public IHttpActionResult Foo() { var bar = new Bar { Message = "Hello" }; return Request.CreateResponse(HttpStatusCode.OK, bar, new MediaTypeHeaderValue("application/json")); } 

另一种可能性是使用ApiController.Content方法:

 public IHttpActionResult Foo() { var bar = new Bar { Message = "Hello" }; return Content(HttpStatusCode.OK, bar, new JsonMediaTypeFormatter(), new MediaTypeHeaderValue("application/json")); } 

编辑:

一种可能性是通过读取tge流并使用JSON解析器(如Json.NET)从JSON创建对象,从Request对象中自行读取和反序列化内容:

 public async Task FooAsync() { var json = await Request.Content.ReadAsStringAsync(); var content = JsonConvert.DeserializeObject(json); } 

是的,可以仅为一个类/控制器更改MediaTypeFormatters 。 如果要保存和恢复默认格式化程序,可以按照以下步骤操作:

  • 在请求的开头保存旧的格式化程序
  • 清除格式化程序集合
  • 添加所需的格式化程序
  • 在请求结束时复制旧的格式化程序

我认为这可以通过ActionFilterAttribute轻松完成:

 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] public class ChangeFormatterAttribute : ActionFilterAttribute { private IEnumerable oldFormatters; private MediaTypeFormatter desiredFormatter; public ChangeFormatterAttribute(Type formatterType) { this.desiredFormatter = Activator.CreateInstance(formatterType) as MediaTypeFormatter; } public override void OnActionExecuting(HttpActionContext actionContext) { var formatters = actionContext.ControllerContext.Configuration.Formatters; oldFormatters = formatters.ToList(); formatters.Clear(); formatters.Add(desiredFormatter); base.OnActionExecuting(actionContext); } public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { var formatters = actionExecutedContext.ActionContext.ControllerContext.Configuration.Formatters; formatters.Clear(); formatters.AddRange(oldFormatters); base.OnActionExecuted(actionExecutedContext); } } 

用法:

 [ChangeFormatterAttribute(typeof(JsonMediaTypeFormatter))] public class HomeController : ApiController { public string Get() { return "ok"; } } // ... [ChangeFormatterAttribute(typeof(XmlMediaTypeFormatter))] public class ValuesController : ApiController { public string Get() { return "ok"; } } 

也许你可以让你的媒体类型格式化程序只接受你的控制器处理的类型:

 public class Dog { public string Name { get; set; } } public class DogMediaTypeFormatter : JsonMediaTypeFormatter { public override bool CanReadType(Type type) { return type == typeof (Dog); } } 

可能不是最好的解决方案:我