JsonConvert.DeserializeObjectおよび“ d” WCFのラッパー
質問
デフォルトでは、WCFサービスはJSON応答を" d"でラップします。ラッパーで、解析に問題が見つかりました。
応答がある JsonConvert.DeserializeObject(response)で解析する場合
"{\"d\":\"{\"a0b70d2f-7fe4-4aa2-b600-066201eab82d\":\"Thelma\",\"d56d4d4f-6029-40df-a23b-de27617a1e43\":\"Louise\"}\"}"
エラーが発生しました:
After parsing a value an unexpected character was encoutered: a. Line 1, position 9.
応答を
に変更した場合"{\"a0b70d2f-7fe4-4aa2-b600-066201eab82d\":\"Thelma\",\"d56d4d4f-6029-40df-a23b-de27617a1e43\":\"Louise\"}"
機能しました。
この" d"を解析する方法WCFサービスからのJSON応答をラップしましたか? JSONを解析するより良い方法はありますか?
解決 4
これで" d"を取り除きました。 Regex.Replaceのラッパーと適切な構造のJSON応答の修正
{\"Guid\":\"a0b70d2f-7fe4-4aa2-b600-066201eab82d\",\"Name\":\"Thelma\"}
{\"Guid\":\"d56d4d4f-6029-40df-a23b-de27617a1e43\",\"Name\":\"Lousie\"}\"}
文字列として定義されたGuidとNameを含むクラスも作成します。
次に、
でデシリアライズを試みます
List<myStruct> o = JsonConvert.DeserializeObject<List<myStruct>>(response);
しかしエラーが表示されます
Expected a JsonObjectContract or JsonDictionaryContract for type 'System.Collections.Generic.List`1[mynamespace.myStruct]', got 'Newtonsoft.Json.Serialization.JsonArrayContract'.
コツはどこですか?
他のヒント
ビヘイビア設定で&lt; enableWebScript /&gt;
を使用していると仮定し、それを&lt; webHttp defaultOutgoingResponseFormat =&quot; Json&quot; /&gt;
に置き換えますそして、あなたは素敵できれいなjsonを得るでしょう、「d」はありません; &quot; __ type&quot;
webHttpBindingでenableWebScriptの動作を使用しているように見えます。おそらく代わりにwebHttp動作を使用する必要があります。これにより、「クリーン」になります。 ASP.NET AJAXクライアントJSONの代わりのJSON。
jsonを取得して、 httpなどのオンラインクラスジェネレーターに貼り付けます://httputility.net/json-to-csharp-vb-typescript-class.aspx 。次のように、このjsonオブジェクトを逆シリアル化するコードを提供します(VBの例):
Public Class MyClass
Public Property D As String
End Class
これをプロジェクトに貼り付け、jsonをこのオブジェクトにデシリアライズします。 Dプロパティは、ラップされていないjsonを含む文字列になりました。これは、最後の受信オブジェクトに2回目のシリアル化解除を行う必要があります。クラスを処理する必要があるかわからない場合は、Dの文字列を同じオンラインクラスジェネレーターに貼り付けると、オブジェクトを受け取る型を作成するために必要なコードが得られます!
WebHttpBehaviorに切り替えても、body要素がラップされていないというエラーメッセージが表示される場合は、処理するメソッドのbodyスタイルをWrappedに手動で設定します。次のようにします:
[OperationContract(BodyStyle = WebMessageBodyStyle.Wrapped、...)] 文字列DoSomething(...)
これがお役に立てば幸いです!
&quot; d&quot;という1つのプロパティを持つ逆シリアル化ラッパークラスを作成できます。デシリアライズに成功したら、dプロパティから値を取得します。
たぶんこれが役立ちます。
サービス:
namespace Application.Service
{
[ServiceBehavior(UseSynchronizationContext = false,
ConcurrencyMode = ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.PerCall),
AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class VendorService : IVendorService
{
public List<Vendor> RetrieveMultiple(int start, int limit, string sort, string dir)
{
//I don't do any manual serialization
return new Vendor();
}
}
}
契約:
[ServiceContract(Namespace = "Application.Service.Contracts")]
public interface IVendorService
{
[OperationContract]
[WebInvoke(ResponseFormat=WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
List<Vendor> RetrieveMultiple(int start, int limit, string sort, string dir);
}
私のSvcファイルには次の行のみがあります:
<%@ ServiceHost Service="Application.Service.VendorService" %>
Web.config
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<behaviors>
<endpointBehaviors>
<behavior name="jsonBehavior">
<enableWebScript />
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="DefaultServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<service behaviorConfiguration="DefaultServiceBehavior" name="Application.Service.VendorService">
<endpoint behaviorConfiguration="jsonBehavior" address="" binding="webHttpBinding" contract="Application.Service.Contracts.IVendor" />
</service>