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



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

为了避免自己代码的复杂性,我从头开始设置了一个新项目。Visual Studio社区2015更新2,Azure应用程序服务工具v2.9(如果重要的话)。新项目,Visual C#,云,Azure移动应用程序。

App_StartStartup.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<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;
    }
}

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);
    }
....
}

我建议小心这里提供的答案。在我们在iOS应用程序中使用离线同步表之前,一切都很好。

在我的案例中,它们在没有任何正当理由的情况下崩溃,很可能它们需要一些非默认的序列化程序设置才能正常工作。我用了努诺·克鲁塞斯的溶液,当我恢复时,一切都恢复了正常。

相关内容

  • 没有找到相关文章

最新更新