3

応答ペイロードで許可されたプロパティのみを送信するというビジネス要件があります。たとえば、応答 DTO には複数のプロパティがあり、そのうちの 1 つが SSN です。ユーザーが SSN を表示する権限を持っていない場合、Json 応答に含めたくありません。2 番目の要件は、クライアントがプロパティを表示または変更する権限を持っている場合、null 値を送信することです。2 番目の要件が設定されているため、ユーザーが null に表示できないプロパティは機能しません。null 値を返す必要があります。

うまくいく解決策があります。DTO を反映して expandoObject を作成し、必要なプロパティのみを追加します。これは私のテストで機能しています。

ITextSerializer の実装を見てきました。それを使用して、スキップするプロパティのリストを持つ別のオブジェクトに応答 DTO をラップすることができます。次に、独自の SerializeToString() と SerializeToStream() をロールすることができます。現時点では、他に方法はありません。スキップするプロパティがリクエストごとに変わるため、JsConfig を使用して SerializeFn を作成することはできません。

したがって、ITextSerializer を実装することは良い選択肢だと思います。これが実装されている良い例はありますか? シリアライザーですでに行われたすべてのハードワークを使用して、優れたパフォーマンスを活用したいと思います。理想的な世界では、見るために WriteType.WriteProperties() にチェックを追加するだけで済み、プロパティは書き込む必要があると思いますが、それは内部的なものであり、実際にはほとんどのものなので、実際には取ることができませんそれらの利点。

誰かが洞察力を持っているなら、私に知らせてください!多分私は ITextSerialzer の実装を実際よりもずっと難しくしているでしょうか?

ありがとう!

プル リクエスト#359は、プロパティ「ExcludePropertyReference」を JsConfig および JsConfigScope に追加しました。必要に応じて、スコープ内の参照を除外できるようになりました。

4

1 に答える 1

0

独自のシリアライザーを作成するのはためらわれます。既存の ServiceStack コードにプラグインできるソリューションを見つけようと思います。そうすれば、dll の更新や破壊的な変更について心配する必要が少なくなります。

考えられる解決策の 1 つは、プロパティ値を反映して覆い隠すことができるカスタム属性でプロパティを装飾することです。これは、シリアライゼーションが発生する前にサービスで実行できます。これには、ユーザーが表示する権限を持っていない値が含まれますが、これらのプロパティを無効にすると、とにかく JSON によってシリアル化されることさえないと主張します。すべてのプロパティを同じに保つと、厳密に型指定された DTO の利点が維持されます

これを実証するために私がすぐに思いついたハッキーなコードを次に示します。これをプラグインに移動し、ある種のプロパティ キャッシュを使用してリフレクションを高速化しますが、アイデアは得られると思います。

次のルートを使用して URL に 2 回アクセスし、実際の動作を確認してください。

  • /test?役割
  • /test?role=Admin (認証されたリクエストのふりをするためのハック)
[System.AttributeUsage(System.AttributeTargets.Property)]
public class SecureProperty : System.Attribute
{
    public string Role {get;set;}

    public SecureProperty (文字列の役割)
    {
        役割 = 役割;
    }
}

[ルート("/テスト")]
public class Test : IReturn
{
    パブリック文字列の名前 {get; 設定; }

    [SecureProperty("管理者")]
    公開文字列 SSN { get; 設定; }

    公開文字列 SSN2 { get; 設定; }

    public string Role {get;set;}
}

public class TestService : サービス
{
    public object Get(テストリクエスト)
    {   
        // ハックしてロールをデモします。
        var usersCurrentRole = request.Role;

        var props = typeof(Test).GetProperties()
        。どこ(
            prop => ((SecureProperty[])prop
                .GetCustomAttributes(typeof(SecureProperty), false))
                .Any(att => att.Role != usersCurrentRole)
        );

        var t = 新しいテスト() {
            名前 = "ジョー",
            SSN = "123-45-6789",
            SSN2 = "123-45-6789" };

        foreach(小道具の変数 p) {
            p.SetValue(t, "xxx-xx-xxxx", null);
        }

        t を返します。
    }
}

Require().StartHost("http://localhost:8080/",
    configurationBuilder: ホスト => { });

このデモはScriptCSで作成します。見てみな。

于 2013-07-27T15:50:49.783 に答える