2016-04-29 19 views
2

Azure Mobile AppでJSONシリアル化をカスタマイズできないようです。Azure Mobile App jsonシリアル化をカスタマイズしています

私自身のコードの複雑さを避けるために、私は最初から新しいプロジェクトをセットアップしました。 Visual Studio Community 2015 Update 2、Azure App Service Tools v2.9(問題がある場合)新しいプロジェクト、Visual C#、Cloud、Azure Mobile App

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

これは私がしようとしたものです::

App_Start\Startup.MobileApp.csでは、このテンプレートには何がある

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

解決しましたか?モバイルアプリがシリアライザ設定を尊重していないのと同様の問題が発生しているようです。私の場合、参照ループの処理は動作していないので、500の応答が発生します。 – DevNoob

答えて

2

これに多くの時間を費やしてから、MobileAppControllerConfigProviderを作成してWithMobileAppControllerConfigProviderに渡すことをお勧めします。

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

そして:

これは私がJsonConvert.DefaultSettingsを尊重するすべてのコントローラを取得するために、やっていることですDevNoobの答えとして

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; 
    } 
} 
+0

ありがとうございます!これは私の回避策よりもはるかに良い方法です! – DevNoob

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

} 

あなたはので、そこSetSerializerSettings()を置くことはできませんのでConfigurationプロパティは、コンストラクタで設定されていません上書きされます。これらの設定は、プロセスが実行されている間は持続するように見えるので、これは少し冗長ですが、仕事を完了させるように見えます。私は誰かが来て、それを行う正しい方法を提供することを願っています!

+0

私の場合は、Initializeをオーバーライドするベースコントローラを実行しました。すべての設定にアクセスできます。 –

1

を、OWIN起動クラスのシリアライザの設定はありませんワーキング。設定が各contollerクラスのInitialize(HttpControllerContextControllerContext)メソッドにある場合は、動作します。私の場合、私は、自己参照の問題を抱えているので、私はこのような問題を解決した:

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

.... 

} 
0

私はここで提供さ答えと注意して、お勧めします。 iOSアプリでオフライン同期表を使用するまではすべて問題ありません。

私の場合は、正当な理由なくクラッシュしました。ほとんどの場合、デフォルト以外のシリアライザ設定が正しく機能する必要があります。 Nuno Crusesのソリューションを使用しましたが、元に戻りました。

関連する問題