我有一个web api,其中全局配置配置为使用: XmlMediaTypeFormatter
我的问题是我不会使用新的控制器来扩展这个web api,而是使用JsonMediaTypeFormatter。
是否可以仅为一个API控制器类将MediaTypeFormatter更改为JSON?
我的问题不是返回JSON,我已经通过返回HttpResponseMessage来解释这个:
return new HttpResponseMessage
{
Content = new ObjectContent<string>("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调用该操作时,它失败了。
答案 0 :(得分:3)
您可以让控制器返回IHttpActionResult
并使用扩展方法HttpRequestMessageExtensions.CreateResponse<T>
并指定您要使用的格式化程序:
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"));
}
修改强>
一种可能性是自己从Request
对象读取和反序列化内容,方法是读取tge流并使用JSON解析器(如Json.NET)从JSON创建对象:
public async Task<IHttpActionResult> FooAsync()
{
var json = await Request.Content.ReadAsStringAsync();
var content = JsonConvert.DeserializeObject<VMRegistrant>(json);
}
答案 1 :(得分:1)
是的,可以仅为一个类/控制器更改MediaTypeFormatters
。如果要保存和恢复默认格式化程序,可以按照以下步骤操作:
我认为这可以通过ActionFilterAttribute
轻松完成:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
public class ChangeFormatterAttribute : ActionFilterAttribute
{
private IEnumerable<MediaTypeFormatter> 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";
}
}
答案 2 :(得分:0)
也许您可以让媒体类型格式化程序只接受控制器处理的类型:
public class Dog
{
public string Name { get; set; }
}
public class DogMediaTypeFormatter : JsonMediaTypeFormatter
{
public override bool CanReadType(Type type)
{
return type == typeof (Dog);
}
}
可能不是最好的解决方案:我