0

Web API で使用するリクエスト エンドポイントがあります。

 public HttpResponseMessage Create(IList<SlideContent> l)
    {
        ...
    }

パラメータをjsonとして送信し、Web APIがそれをIListにシリアル化します

SlideContent は次のとおりです。

public abstract class SlideItem
    {
       ...
    }

そして私は専門のクラスを持っています

    public class TitleSlideItem : SlideItem
    {
        ...
    }


    public class ParagraphSlideItem : SlideItem
    {
       ...
    }

そのように、私は Create 関数を呼び出すことができません。

missingmethodexception: 抽象クラスを作成できません

そのため、json パラメータを逆シリアル化できません。抽象修飾子を削除すると、特殊なオブジェクトがなくなり、すべてのオブジェクトの型が になりますSlideContent。私はjsonに注釈を入れましたが、どちらも役に立ちません。

私が間違っていなければ、抽象クラス用のカスタム バインダーを作成する必要がありますが、どうすればそれを行うことができますか?

心から、

ゾリ

4

2 に答える 2

2

1 つの可能性は、組み込みの JSON シリアライザーを、次のブログ投稿に示されているように、JSON.NET を使用するカスタム フォーマッターに置き換えることです。

public class JsonNetFormatter : MediaTypeFormatter
{
    private JsonSerializerSettings _jsonSerializerSettings;

    public JsonNetFormatter(JsonSerializerSettings jsonSerializerSettings)
    {
        _jsonSerializerSettings = jsonSerializerSettings ?? new JsonSerializerSettings();

        // Fill out the mediatype and encoding we support
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
        Encoding = new UTF8Encoding(false, true);
    }

    protected override bool CanReadType(Type type)
    {
        if (type == typeof(IKeyValueModel))
        {
            return false;
        }

        return true;
    }

    protected override bool CanWriteType(Type type)
    {
        return true;
    }

    protected override Task<object> OnReadFromStreamAsync(Type type, Stream stream, HttpContentHeaders contentHeaders, FormatterContext formatterContext)
    {
        // Create a serializer
        JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);

        // Create task reading the content
        return Task.Factory.StartNew(() =>
        {
            using (StreamReader streamReader = new StreamReader(stream, Encoding))
            {
                using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader))
                {
                    return serializer.Deserialize(jsonTextReader, type);
                }
            }
        });
    }

    protected override Task OnWriteToStreamAsync(Type type, object value, Stream stream, HttpContentHeaders contentHeaders, FormatterContext formatterContext, TransportContext transportContext)
    {
        // Create a serializer
        JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);

        // Create task writing the serialized content
        return Task.Factory.StartNew(() =>
        {
            using (JsonTextWriter jsonTextWriter = new JsonTextWriter(new StreamWriter(stream, Encoding)) { CloseOutput = false })
            {
                serializer.Serialize(jsonTextWriter, value);
                jsonTextWriter.Flush();
            }
        });
    }
}

次にApplication_Start、フォーマッターを登録するときに、JSON の型情報を使用するようにシリアライザーを構成できます。

var formatters = GlobalConfiguration.Configuration.Formatters;
formatters.Remove(formatters.XmlFormatter);
formatters.Remove(formatters.JsonFormatter);

var serializerSettings = new JsonSerializerSettings();
serializerSettings.TypeNameHandling = TypeNameHandling.Objects;
serializerSettings.Converters.Add(new IsoDateTimeConverter());
formatters.Add(new JsonNetFormatter(serializerSettings));

そして、次の JSON を POST できます。

[
    { 
        "$type":"AppName.Models.TitleSlideItem, AppName",
        "Id":1,
        "Title":"some title" // this is a specific property of the TitleSlideItemclass
    },
    {
        "$type":"AppName.Models.ParagraphSlideItem, AppName",
        "Id":2,
        "Paragraph":"some paragraph" // this is a specific property of the ParagraphSlideItem class
    }
]

このアクション内で正常に逆シリアル化されます。

public HttpResponseMessage Post(IList<SlideItem> l)
{
    ...
}
于 2012-04-25T11:56:31.003 に答える
1

JsonFx creates custom binders. For example take a look at:

https://code.google.com/p/jsonfx/source/browse/trunk/JsonFx/JsonFx.MvcTemplate/Global.asax.cs

Look at the RegisterBinders() function in that file and the source to the binders or just install JsonFx and create a project using their MVC template and see how they do it or just use their library if that would work for you. That's what I would do.

于 2012-07-18T23:00:46.800 に答える