7

ASP.NET MVC で REST API を作成しています。リクエストとレスポンスのフォーマットは JSON または XML にしたいのですが、別のデータ フォーマットを簡単に追加できるようにしたり、最初に XML だけを作成して後で JSON を追加したりできるようにしたいと考えています。

基本的に、API GET/POST/PUT/DELETE リクエストのすべての内部動作を指定したいのですが、データがどのような形式で入ってきたのか、何を残すのかを考える必要はありません。後で形式を簡単に指定したり、変更したりできます。クライアントごと。したがって、1 人が JSON を使用し、1 人が XML を使用し、1 人が XHTML を使用できます。その後、大量のコードを書き直すことなく、別の形式を追加することもできました。

すべてのアクションの最後に一連の if/then ステートメントを追加し、それによってデータ形式を決定する必要はありません。インターフェイスや継承などを使用してこれを行う方法があると思います。最善のアプローチがわからないだけです。

4

2 に答える 2

7

シリアル化

ASP.NET パイプラインは、このために設計されています。コントローラー アクションはクライアントに結果を返すのではなくActionResult、ASP.NET パイプラインの次のステップで処理される結果オブジェクト ( ) を返します。ActionResultクラスをオーバーライドできます。FileResult, JsonResult, ContentResultFileContentResultは MVC3 以降に組み込まれていることに注意してください。

あなたの場合、おそらくRestResultオブジェクトのようなものを返すのが最善です。そのオブジェクトは、ユーザーの要求 (または追加の規則) に従ってデータをフォーマットする責任があります。

public class RestResult<T> : ActionResult
{
    public override void ExecuteResult(ControllerContext context)
    {
        string resultString = string.Empty;
        string resultContentType = string.Empty;

        var acceptTypes = context.RequestContext.HttpContext.Request.AcceptTypes;

        if (acceptTypes == null)
        {
            resultString = SerializeToJsonFormatted();
            resultContentType = "application/json";
        }
        else if (acceptTypes.Contains("application/xml") || acceptTypes.Contains("text/xml"))
        {
            resultString = SerializeToXml();
            resultContentType = "text/xml";
        }

       context.RequestContext.HttpContext.Response.Write(resultString);
        context.RequestContext.HttpContext.Response.ContentType = resultContentType;
   }
}

逆シリアル化

これはもう少しトリッキーです。Deserialize<T>基本コントローラ クラスのメソッドを使用しています。応答全体を読み取るとサーバーがオーバーフローする可能性があるため、このコードは本番環境に対応していないことに注意してください。

protected T Deserialize<T>()
{
    Request.InputStream.Seek(0, SeekOrigin.Begin);
    StreamReader sr = new StreamReader(Request.InputStream);
    var rawData = sr.ReadToEnd(); // DON'T DO THIS IN PROD!

    string contentType = Request.ContentType;

    // Content-Type can have the format: application/json; charset=utf-8
    // Hence, we need to do some substringing:
    int index = contentType.IndexOf(';');
    if(index > 0)
        contentType = contentType.Substring(0, index);
    contentType = contentType.Trim();

    // Now you can call your custom deserializers.
    if (contentType == "application/json")
    {
        T result = ServiceStack.Text.JsonSerializer.DeserializeFromString<T>(rawData);                
        return result;
    }
    else if (contentType == "text/xml" || contentType == "application/xml")
    {
        throw new HttpException(501, "XML is not yet implemented!");
    }
}
于 2011-06-08T14:59:46.980 に答える
0

参照用にこれをここに載せたかっただけですが、ASP.NET MVC を使用するのが最善の方法ではない可能性があることを発見しました。

Windows Communication Foundation (WCF) は、Web およびエンタープライズ全体で通信するサービス指向アプリケーションを迅速に構築するための統合プログラミング モデルを提供します。

今日の Web アプリケーション開発者は、データとサービスを公開する方法に関する新たな課題に直面しています。クラウド、デバイスへの移行、jQuery などのブラウザー ベースのフレームワークへの移行により、これらの機能を Web フレンドリーな方法で表示する必要性が高まっています。WCF の Web API オファリングは、開発者がこの新しい世界で動作するシンプルかつ強力なアプリケーションを作成するためのツールを提供することに重点を置いています。HTTP 経由で公開するだけでなく、さらに先へ進みたい開発者の場合、当社の API を使用すると、HTTP の豊富な機能すべてにアクセスし、アプリケーション開発に RESTful 制約を適用できます。この作業は、.Net 4.0 で既に出荷されている HTTP/ASP.NET AJAX 機能の進化版です。

http://wcf.codeplex.com/

ただし、これが私が取ろうとしているルートであるという事実にもかかわらず、実際には質問に答えていないため、これを答えとして選択しません。将来の研究者に役立つようにここに置きたかっただけです。

于 2011-06-08T17:28:51.453 に答える