「マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
WCF や ASP.NET Web API で、指定の JSON を返す(送信する)方法を説明する。
WCF で JSON を返す場合、既定では DataContractJsonSerializer? が使用される。
以下に注意する。
[ServiceContract]
public interface IJSONService
{
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "GetJson")]
Sample GetJson();
}
public class JSONService : IJSONService
{
public Sample GetJson()
{
// JSON にシリアライズする元となるオブジェクトを作成する
Sample sample = new Sample()
{
StringKey = "StringValue",
IntKey = 123,
ListKey = new List<string>() { "List1", "List2", "List3" }
};
// クライアントにデータを返す
return sample;
}
}
public class Sample
{
public string StringKey { get; set; }
public int IntKey { get; set; }
public List<string> ListKey { get; set; }
}<system.serviceModel>
<services>
<service name="WebApplication1.JSONService">
<endpoint address="" binding="webHttpBinding" behaviorConfiguration="MyBehavior"
contract="WebApplication1.IJSONService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="MyBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
</system.serviceModel>{"IntKey":123,"ListKey":["List1","List2","List3"],"StringKey":"StringValue"}[ServiceContract]
public interface IJSONService2
{
[OperationContract]
[WebGet(UriTemplate = "GetJson")]
Message GetJson();
}
public class JSONService2 : IJSONService2
{
public Message GetJson()
{
// JSON にシリアライズする元となるオブジェクトを作成する
Sample2 sample = new Sample2()
{
key = new Dictionary<string, string>()
{
{"key1", "value1"},
{"key2", "value2"},
{"key3", "value3"}
}
};
// JSON.NET を使用して JSON 形式にシリアライズ
string jsonStr = JsonConvert.SerializeObject(sample);
// 'X-Content-Type-Options: nosniff' ヘッダーを追加する
WebOperationContext.Current.OutgoingResponse.Headers.Add("X-Content-Type-Options", "nosniff");
// JSON を返す
return WebOperationContext.Current.CreateTextResponse(jsonStr,
"application/json; charset=utf-8",
Encoding.UTF8);
}
}
public class Sample2
{
public Dictionary<string, string> key { get; set; }
}<system.serviceModel>
<services>
<service name="WebApplication1.JSONService2">
<endpoint address="" binding="webHttpBinding" behaviorConfiguration="MyBehavior"
contract="WebApplication1.IJSONService2" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="MyBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
</system.serviceModel>{"key":{"key1":"value1","key2":"value2","key3":"value3"}}WCF における JSON 処理の参考情報
ASP.NET との互換性がないため、サービスをアクティブにできません。 このアプリケーションでは、ASP.NET との互換性が有効になっています。 web.config 内で ASP.NET の互換性モードを無効にするか、 RequirementsMode に Allowed または Required が設定されたサービスの型に、 AspNetCompatibilityRequirements 属性を追加してください。
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] public class CalculatorService : ICalculatorSession
にあるように、サービスのクラスに、
AspNetCompatibilityRequirements? 属性を追加する。
ASP.NET Web API は、既定で JSON.NET によって Serialize される。このため、Dictionary 型も問題なく Serialize できる。
Web API の返すJSONフォーマット(JSONシリアライズのフォーマット)をWebApiConfigで、以下のように指定できる。
// JSON データにはCamelCaseを使用 (JSON.NET) config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
public class ValuesController : ApiController
{
// GET api/values
public Sample Get()
{
// JSON にシリアライズする元となるオブジェクトを作成する
Sample sample = new Sample()
{
key = new Dictionary<string, string>()
{
{"key1", "value1"},
{"key2", "value2"},
{"key3", "value3"}
}
};
// JSON を返す
return sample;
}
}
public class Sample
{
public Dictionary<string, string> key { get; set; }
}{"key":{"key1":"value1","key2":"value2","key3":"value3"}}Java など、他プラットフォームとの相互運用を行なう際に注意すべき点。
既定の DataContractJsonSerializer では、Dictionary 型のオブジェクトを正しく扱えない。
Dictionary 型のオブジェクトを扱う場合は、JSON.NET など、その他のSerializerを使用する。
Java などの他プラットフォームとの相互運用を考えた場合、
いきなりPOJO または POCO をデータコントラクトとせず、
先ずは出力したい JSON フォーマットを確認する事から始める。
以下の手順で、
数個、Microsoft Azure が公開している REST API をピックアップした。
resourceGroup の name が REST の Uri に含まれていて、Responce が JSON 形式で返されます
Responce が HTTP 200 だけのもあります
呼び出すパラメタが大きく、変更を加える操作は、PUT で行われ、Request Body に パラメタが JSON 形式で渡されます。
これらの REST API でも、JSON のフォーマットが明記されており、
JSON フォーマットレベルでデータコントラクトを結ぶ必要がある。
DataContractJsonSerializer?は、
WCFのデータコントラクトのSerializerとして使用されていたこともあり、
などの問題があった。
データコントラクト不要な単方向のやり取りのために、JavaScriptSerializer?などのクラスも追加されたが、
これは、.NET3.5でサポートされなくなり、替わって、JSON.NETがデファクトになり、ASP.NET Web API の標準のシリアライザに採用された。
Tags: :.NET開発, :通信技術, :.NET Standard, :.NET Core, :ASP.NET, :ASP.NET Web API