从MVC 4 Web Api返回匿名类型失败,出现序列化错误
我刚刚开始使用MVC 4 Web API,我似乎误解了它是如何工作的。
在Web API之前,我有一个像这样的简单MVC操作方法:
public JsonResult User() { return Json(new { firstName = "Joe", lastName = "Jacobs", email = "joe.jacobs@gmail.com" }); }
那会很好。 在新的Web API控制器中,我正在尝试做类似的事情。
public object User() { return new { firstName = "Joe", lastName = "Jacobs", email = "joe.jacobs@gmail.com" } }
这会因序列化错误而失败:
‘ObjectContent`1’类型无法序列化内容类型’application / xml的响应主体; 字符集= UTF-8’ 。
内部exception:
类型’ f__AnonymousType1`3 [System.String,System.String,System.String]’无法序列化。 请考虑使用DataContractAttribute属性对其进行标记,并使用DataMemberAttribute属性标记要序列化的所有成员。 如果类型是集合,请考虑使用CollectionDataContractAttribute对其进行标记。 有关其他受支持的类型,请参阅Microsoft .NET Framework文档。
关于从API控制器返回匿名类型我不明白的是什么?
如果你看一下Fiddler(我在这里使用Firefox的示例)
默认情况下,来自浏览器的请求将接受 application / xml,而不是application / json
但是,您可以通过添加一个标头来创建来自Fiddler的虚假请求 :
Accept: application/json
它会工作
从链接 :
XML序列化程序不支持匿名类型或JObject实例。 如果将这些function用于JSON数据,则应从管道中删除XML格式化程序,如本文后面所述。
如何删除XmlFormatter
:
var configuration = GlobalConfiguration.Configuration; configuration.Formatters.Remove(configuration.Formatters.XmlFormatter);
您还可以使用JsonMediaTypeFormatter,因此您不需要JSONObject和相关类。 然后,您可以在控制器类中返回动态类型。
public static void Register(HttpConfiguration config) { config.Formatters.Clear(); config.Formatters.Add(new JsonMediaTypeFormatter()); config.MapHttpAttributeRoutes(); } public class YourController : ApiController { [HttpGet, Route("getstuff/{stuffId}")] public dynamic Get(string stuffId) { var stuff = Model.Stuff.Get(stuffId); return new { success= stuff != null, stuffId = stuff.Id, name = stuff.Name }; } }
如果您还想支持Jsonp,您可以inheritanceJsonMediaTypeFormatter并创建自己的JsonpMediaTypeFormatter(也可以在stackoverflow上找到: https ://stackoverflow.com/a/12492552/1138266)。
我发现API不喜欢返回原始列表。 相反,我必须创建一个对象,并将对象的值设置为我的列表; 看到第一个返回声明。
例:
public IHttpActionResult GetMessages(int messageFeedId, int lastMessageId) { List messageDomainObjects = MessageService.GetMessages(messageFeedId, lastMessageId); if (messageDomainObjects.Any()) { var messages = messageDomainObjects.Select(m => new MessageModel( m.Id, m.Message, m.CreatedDate, m.IsActive, new UserModel( m.User.Id, m.User.FirstName, m.User.LastName ) )); return Ok(new { messages = messages }); } else { return Ok(new { }); } }
- 尝试写入事件日志时出错 – 无法打开源“SourceName”的日志。 您可能没有写访问权限
- 使用jQuery从ASP.Net JSON服务获取数据
- 如何在某些方法执行时在aspx页面(WebForms)中显示等待进程
- DataSource和DataSourceID都在’GridView1’上定义。 删除一个定义
- 如何遍历GridView中的每一行,每列和单元格并获取其值
- Azure Mobile Services Web Api上的SignalR CORS
- EnableEventValidation =“false” – 一个好主意?
- 重定向到“谢谢”页面并立即提供下载文件的保存对话框
- 如何将图像裁剪成圆圈?