Azure移动应用程序自定义json序列化

我似乎无法在Azure移动应用程序中自定义JSON序列化。

为了避免我自己的代码的复杂性,我从头开始设置一个新项目。 Visual Studio Community 2015 Update 2,Azure App Service Tools v2.9(如果重要)。 新项目,Visual C#,云,Azure移动应用程序。

App_Start\Startup.MobileApp.cs这是模板中的内容:

 public static void ConfigureMobileApp(IAppBuilder app) { HttpConfiguration config = new HttpConfiguration(); new MobileAppConfiguration() .UseDefaultConfiguration() .ApplyTo(config); // Use Entity Framework Code First to create database tables based on your DbContext Database.SetInitializer(new MobileServiceInitializer()); MobileAppSettingsDictionary settings = config.GetMobileAppSettingsProvider().GetMobileAppSettings(); if (string.IsNullOrEmpty(settings.HostName)) { app.UseAppServiceAuthentication(new AppServiceAuthenticationOptions { // This middleware is intended to be used locally for debugging. By default, HostName will // only have a value when running in an App Service application. SigningKey = ConfigurationManager.AppSettings["SigningKey"], ValidAudiences = new[] { ConfigurationManager.AppSettings["ValidAudience"] }, ValidIssuers = new[] { ConfigurationManager.AppSettings["ValidIssuer"] }, TokenHandler = config.GetAppServiceTokenHandler() }); } app.UseWebApi(config); } 

这是我尝试过的:

 public static void ConfigureMobileApp(IAppBuilder app) { JsonConvert.DefaultSettings = () => new JsonSerializerSettings() { Converters = { new StringEnumConverter { CamelCaseText = true }, }, ContractResolver = new CamelCasePropertyNamesContractResolver { IgnoreSerializableAttribute = true }, DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.Indented }; HttpConfiguration config = new HttpConfiguration(); config.Formatters.JsonFormatter.SerializerSettings = JsonConvert.DefaultSettings(); new MobileAppConfiguration() .UseDefaultConfiguration() .ApplyTo(config); ... } 

运行它并访问http://localhost:53370/tables/TodoItem ,json没有缩进,并且有一堆false字段,显示正在忽略设置。

那么如何更改序列化器设置以便在此配置中遵守它们? 从每个控制器返回一个JsonResult我自己的自定义设置工作,但只允许我发送200 OK状态(我必须跳过箍返回201 Created尊重我的设置)。

Azure Mobile Apps似乎当前不尊重在OWIN启动类中设置的序列化程序设置。 我不知道他们是否被覆盖或者没有被使用但他们没有得到控制器的接收。

作为解决方法,似乎您可以从控制器内部设置序列化程序设置:

 public class SomeController : ApiController { public object Get() { SetSerializerSettings(); Do your logic.... } private void SetSerializerSettings() { this.Configuration.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings { Converters = { new StringEnumConverter { CamelCaseText = true }, }, ContractResolver = new CamelCasePropertyNamesContractResolver { IgnoreSerializableAttribute = true }, DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.Indented }; } } 

Configuration属性尚未在构造函数中设置,因此您无法将SetSerializerSettings()置于其中,因为它会被覆盖。 只要进程正在运行,这些设置似乎就会持续存在,所以这有点多余,但似乎确实完成了工作。 我希望有人可以来并提供正确的方法!

花了很多时间在这之后,我认为你能做的最好的事情就是创建一个MobileAppControllerConfigProvider并将它传递给WithMobileAppControllerConfigProvider

这就是我正在做的,让所有控制器都尊重JsonConvert.DefaultSettings

 JsonConvert.DefaultSettings = () => new JsonSerializerSettings { /* something */ }; var provider = new MobileConfigProvider(); var config = new HttpConfiguration(); config.MapHttpAttributeRoutes(); config.Formatters.Remove(config.Formatters.XmlFormatter); config.Formatters.JsonFormatter.UseDataContractJsonSerializer = false; config.Formatters.JsonFormatter.SerializerSettings = provider.Settings; new MobileAppConfiguration(). MapApiControllers(). AddMobileAppHomeController(). AddPushNotifications(). WithMobileAppControllerConfigProvider(provider). ApplyTo(config); 

和:

 sealed class MobileConfigProvider : MobileAppControllerConfigProvider { readonly Lazy settings = new Lazy(JsonConvert.DefaultSettings); public JsonSerializerSettings Settings => settings.Value; public override void Configure(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor) { base.Configure(controllerSettings, controllerDescriptor); controllerSettings.Formatters.JsonFormatter.SerializerSettings = Settings; } } 

作为DevNoob的回答,OWIN启动类中的序列化程序设置无效。 当设置在每个控制器类的Initialize(HttpControllerContext controllerContext)方法中时,它可以工作。 在我的情况下,我有自引用问题,所以我解决了这样的问题:

 public class CustomerController : TableController { protected override void Initialize(HttpControllerContext controllerContext) { controllerContext.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; base.Initialize(controllerContext); MyMobileAppContext context = new MyMobileAppContext(); DomainManager = new EntityDomainManager(context, Request); } .... } 

我建议小心这里提供的答案。 一切都很好,直到我们在iOS应用程序中使用脱机同步表。

在我的情况下,他们没有任何理由崩溃,很可能他们需要一些非默认的序列化设置才能正常运行。 我使用了Nuno Cruses的解决方案,当我恢复时,所有人都恢复正常。