3

@mythz https://stackoverflow.com/a/12413091/1095655によるこの投稿を読みましたが、私の評判はコメントできるほど高くありません

私は仕事をするのに問題があります。バージョン 1 の DTO で要求を受け取った場合、バージョン 1 の DTO には Version プロパティがないため、送信されたデータにはバージョンが含まれていません。ServiceStack が要求を逆シリアル化すると、バージョンが 2 に設定された DTO オブジェクト (バージョン 3) が作成されます。送信されたデータからバージョンが受信されないため、予想どおり、バージョンは 0 にオーバーライドされません。私が見たように、最初からバージョンを DTO に実装する必要があります。そうしないと機能しません。

うまくいけば、私は間違っていて、誰かが私が欠けているものを明確にすることができますか? バージョンが実装されていない DTO が本番環境にあるため、これを解決できますか?

4

1 に答える 1

3

コンストラクターにバージョン番号が必要なため、最初に情報を追加するときは注意がVersion必要です。これにより、新しい DTO に逆シリアル化するたびに同じコンストラクターが使用されると同時に、各呼び出しに暗黙的なバージョンが割り当てられます。

残念ながら、元の DTO には Version がないため、ワイヤ上にシリアル化されていないため、暗黙的に割り当てられた Version フィールドをオーバーライドすることはありません。

これを回避する (そしてコンストラクターで暗黙的に割り当てられたバージョン番号を保持する) には、逆シリアル化で使用されるバージョンを効果的にリセットする必要があります。

JSON/JSVJsConfig.ModelFactoryシリアライザーで on App_Start をオーバーライドすることでこれを行うことができます (つまり、AppConfig で)。これにより、デシリアライゼーションで使用される各 POCO タイプに対して作成されたインスタンスを制御できます。

この場合、バージョンを持つ DTO をリセットして0、バージョン番号のない DTO が割り当てられ、バージョン番号を持つ DTO0がそれをオーバーライドするように戻します。

 JsConfig.ModelFactory = type => {
    if (typeof(IHasVersion).IsAssignableFrom(type))
    {
        return () => {
            var obj = (IHasVersion)type.CreateInstance();
            obj.Version = 0;
            return obj;
        };
    }
    return () => type.CreateInstance();
};

IHasVersionここでは簡単にするために明示的なインターフェイスを使用していますが、リフレクションを使用して、バージョン番号を含む型を簡単に検出して再割り当てすることもできます。

暗黙的に割り当てられたバージョン番号を持つ DTO に逆シリアル化する Version プロパティのない元の DTO の例を次に示します。

public class Dto
{
    public string Name { get; set; }
}

public interface IHasVersion
{
    int Version { get; set; }
}

public class DtoV1 : IHasVersion
{
    public int Version { get; set; }
    public string Name { get; set; }

    public DtoV1()
    {
        Version = 1;
    }
}

元の DTO を新しいDtoV1ものに逆シリアル化すると、0 のままになります。

var dto = new Dto { Name = "Foo" };
var fromDto = dto.ToJson().FromJson<DtoV1>();
fromDto.Version // 0
fromDto.Name    // Foo

新しい DTO を使用すると、バージョン番号が入力されます。

var dto1 = new DtoV1 { Name = "Foo 1" };
var fromDto1 = dto1.ToJson().FromJson<DtoV1>();
fromDto.Version // 1
fromDto.Name    // Foo 1
于 2012-11-03T00:13:25.520 に答える