1

URL パス パラメータを受け取る POST エンドポイントがあり、本文は送信された DTO のリストです。

したがって、現在、リクエスト DTO は次のように見えます。

[Route("/prefix/{Param1}", "POST")]
public class SomeRequest
{
    public string          Param1  { get; set; }
    public List<SomeEntry> Entries { get; set; }
}

public class SomeEntry
{
    public int    ID    { get; set; }
    public int    Type  { get; set; }
    public string Value { get; set; }
}

サービスメソッドは次のようになります。

public class SomeService : Service
{
    public SomeResponse Post(SomeRequest request)
    {
    }
}

JSON でエンコードする場合、クライアントは POST 本文を次のようにエンコードする必要があります。

{
    "Entries":
    [
        {
            "id":    1
            "type":  42
            "value": "Y"
        },
        ...
    ]
}

これは冗長です。クライアントに次のようなデータを送信してもらいたいです:

[
    {
        "id":    1
        "type":  42
        "value": "Y"
    },
    ...
]

私のリクエスト DTO が単にList<SomeEntry>

私の質問は次のとおりです。このようにリクエストを「平坦化」する方法はありますか? または、要求の 1 つのプロパティをメッセージ本文のルートとして指定しますか? つまり、おそらく:

[Route("/prefix/{Param1}", "POST")]
public class SomeRequest
{
    public string          Param1  { get; set; }
    [MessageBody]
    public List<SomeEntry> Entries { get; set; }
}

これは ServiceStack で何らかの方法で実行できますか?

4

2 に答える 2

0

OK私はこれを達成することができました。最も美しい解決策ではありませんが、今のところは十分です。

JSON のコンテンツ タイプ フィルターをラップしました。

var serz   = ContentTypeFilters.GetResponseSerializer("application/json");
var deserz = ContentTypeFilters.GetStreamDeserializer("application/json");
ContentTypeFilters.Register("application/json", serz, (type, stream) => MessageBodyPropertyFilter(type, stream, deserz));

次に、カスタム デシリアライザーは次のようになります。

private object MessageBodyPropertyFilter(Type type, Stream stream, StreamDeserializerDelegate original)
{
    PropertyInfo prop;
    if (_messageBodyPropertyMap.TryGetValue(type, out prop))
    {
        var requestDto = type.CreateInstance();
        prop.SetValue(requestDto, original(prop.PropertyType, stream), null);
        return requestDto;
    }
    else
    {
        return original(type, stream);
    }
}

_messageBodyPropertyMap私の元の質問の例のように、リクエストDTOをスキャンして特定の属性を探すことにより、initの後にデータが入力されます。

于 2013-10-04T17:52:12.707 に答える