2012-04-20 4 views
1

私はMonoDroidプロジェクトでJsonのシリアル化/逆シリアル化にServiceStackを使用しようとしています。ServiceStackでのエラーMonoDroidでのJSON処理

私はMonoDroid環境で実行するためにServiceStackを構築しましたが、今はJSONの逆シリアル化に問題があります。

例コード: 未処理の例外:

System.ArgumentNullException: Argument cannot be null. 
Parameter name: method 

スタックトレース:デシリアライゼーションで

public class Track 
{ 
     public string Id { get; set; } 
     public string Title { get; set; } 
     public string Artist { get; set; } 
     public string Hash { get; set; } 
     public string Type { get; set; } 
    } 
} 
... 
var track = new Track { Id = "1", Artist = "artist name", Hash = "654874", Title = "song title", Type = "mp3", }; 
var json = ServiceStack.Text.JsonSerializer.SerializeToString(track); 
var track1 = ServiceStack.Text.JsonSerializer.DeserializeFromString<Track>(json); 

I例外有する私が見るよう

[External Code] 
0x5E in ServiceStack.Text.Json.JsonReader.GetParseFn at [...]\Android\ServiceStack.Text\src\ServiceStack.Text\Json\JsonReader.Generic.cs:36 C# 
0x2 in ServiceStack.Text.Json.JsonTypeSerializer.GetParseFn at [...]\Android\ServiceStack.Text\src\ServiceStack.Text\Json\JsonTypeSerializer.cs:283 C# 
0xF in ServiceStack.Text.Common.TypeAccessor.Create at [...]\Android\ServiceStack.Text\src\ServiceStack.Text\Common\DeserializeType.cs:146 C# 
0x142 in ServiceStack.Text.Common.DeserializeType`1[[ServiceStack.Text.Json.JsonTypeSerializer, ServiceStack.Text, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].GetParseMethod at [...]\Android\ServiceStack.Text\src\ServiceStack.Text\Common\DeserializeType.cs:60 C# 
0x43A in ServiceStack.Text.Common.JsReader`1[[ServiceStack.Text.Json.JsonTypeSerializer, ServiceStack.Text, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].GetParseFn at [...]\Android\ServiceStack.Text\src\ServiceStack.Text\Common\JsReader.cs:100 C# 
0x6 in ServiceStack.Text.Json.JsonReader`1[[Database.Models.Track, AssemblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]..cctor at [...]\Android\ServiceStack.Text\src\ServiceStack.Text\Json\JsonReader.Generic.cs:58 C# 
0x1B in ServiceStack.Text.JsonSerializer.DeserializeFromString at [...]\Android\ServiceStack.Text\src\ServiceStack.Text\JsonSerializer.cs:33 C# 

がある:

var genericType = typeof(JsonReader<>).MakeGenericType(type); 
var mi = genericType.GetMethod("GetParseFn", BindingFlags.Public | BindingFlags.Static); 
parseFactoryFn = (ParseFactoryDelegate)Delegate.CreateDelegate(typeof(ParseFactoryDelegate), mi); 

genericTypeは "可能System.String" だから

、そこに "MI" は変数がnullである "ServiceStack.Text.Json.JsonReader`1は[可能System.String]" タイプがある

任意のですアイデアをどのように修正するか、またはどこを見るか?

ありがとうございました。

答えて

5

ビルド構成でlinkingが有効になっていて、明示的に参照されていないため、GetParseFn()メソッドがリンクされていたという問題がありました。

リンカーは、Androidのビルドプロセス用のMonoの一部として含まれる静的解析ツールです。コンパイルされたアプリケーションをスキャンし、明示的に参照されていない.NET(またはこの場合はコンパイルされたServiceStackクラスライブラリ)の部分を実際に削除します。これは、アプリケーションのサイズを減らすための長い道のりですが、ここに示すように、問題にぶつかることがあります。 GetParseFn()メソッドは明示的に参照されていないため(リフレクションを介して呼び出されています)、リンカーは必要とされず、リンクされていることを知らなかった。

今後この問題を処理する方法はいくつかあります。

  1. 完全に無効にする:プロジェクトのプロパティでリンクを無効にすることができます。一般的には、デバッグビルドのためにそれを残す方が簡単ですし、リリースビルドのためにオンにする方が簡単です。もちろん、リリースビルドを計画している場合、これは完全な解決策ではありません。
  2. SDKアセンブリのみをリンクする:このオプションは、リンカーに.NET BCLおよびAndroid SDKでの操作のみを指示し、ライブラリを単独で残します。
  3. 使用PreserveAttribute:この属性を使用すると、明示的に参照されていなくても必要なことが分かっている特定の部分を残すようにリンカーに指示できます。 ServiceStackは外部ライブラリであり、独自のものではないので、これはおそらくこの場合は最善の解決策ではありません。
  4. Use Linkskip:このオプションを使用すると、リンカーに触れてはならない特定のアセンブリを指定できます。リンカーをオンのままにして、必要に応じてオプトアウトすることができます。

個人的には、あなたの状況では、私はLinkskipルートに行くことを提案することができます。リンカーのすべての利点を引き続き得ることができますが、このような問題を避けるためにServiceStackを無視してください。あなたのプロジェクトファイルでは、次の行に沿って何かで終わるでしょう:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> 
    <AndroidLinkMode>Full</AndroidLinkMode> 
    <AndroidLinkSkip>ServiceStack.Text</AndroidLinkSkip> 
</PropertyGroup> 
+0

これは私の問題です。 ** PreserveAttribute **を使って解決すると思います。説明をありがとう。 – Anton