我似乎无法在Azure移动应用程序中自定义JSON序列化。
为了避免我自己的代码的复杂性,我从头开始设置一个新项目。 Visual Studio社区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
)。
答案 0 :(得分:3)
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()
放在那里,因为它会被覆盖。只要进程正在运行,这些设置似乎就会持续存在,所以这有点多余,但它似乎确实完成了工作。我希望有人可以来并提供正确的方法来做到这一点!
答案 1 :(得分:2)
在花了很多时间之后,我认为你能做的最好的事情是创建一个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<JsonSerializerSettings> settings = new Lazy<JsonSerializerSettings>(JsonConvert.DefaultSettings);
public JsonSerializerSettings Settings => settings.Value;
public override void Configure(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor)
{
base.Configure(controllerSettings, controllerDescriptor);
controllerSettings.Formatters.JsonFormatter.SerializerSettings = Settings;
}
}
答案 2 :(得分:1)
作为DevNoob的回答,OWIN启动类中的序列化程序设置无法正常工作。当设置在每个控制器类的Initialize(HttpControllerContext controllerContext)方法中时,它可以工作。就我而言,我有自引用问题,所以我解决了这个问题:
public class CustomerController : TableController<Customer>
{
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<Customer>(context, Request);
}
....
}
答案 3 :(得分:0)
我建议小心这里提供的答案。在iOS应用程序中使用脱机同步表之前,一切都很好。
在我的情况下,他们没有任何理由崩溃,很可能他们需要一些非默认的序列化设置才能正常运行。我使用了Nuno Cruses的解决方案,当我恢复时,所有人都恢复正常。