Wcf rest json возвращает динамический список

Как я могу вернуть объект, содержащий динамический список?

У меня есть работающая служба REST, в которой я хочу вернуть данные JSON. В большинстве случаев это работает очень хорошо, за исключением одного:

В этом конкретном случае у меня есть List<Bla>, который может содержать объекты типа Bla и Bla1 (который наследуется от Bla). Как только я добавляю Bla1 в список, в моем браузере появляется ошибка.

Firefox: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://.../DoSomething. (Reason: CORS request did not succeed).

Chrome: GET https://.../DoSomething net::ERR_SPDY_PROTOCOL_ERROR

Как я могу вернуть объект, содержащий динамический список?

Классы

[DataContract]
public class Blibla
{
    [DataMember] public bool requestSuccess;
    [DataMember] List<Blubb> blubb;
    [DataMember] List<Bla> blas;

    public Blibla(bool success)
    {
        this.requestSuccess = success;
        blubb = new List<Blubb>() { new Blubb(11, "einser"), new Blubb(22, "zweier"), new Blubb(33, "dreier") };
        blas = new List<Bla>() { new Bla(11), new Bla1(22, 22) };
    }
}

[DataContract]
public class Bla
{
    [DataMember] public int id;

    public Bla(int id)
    {
        this.id = id;
    }
}

[DataContract]
public class Bla1 : Bla
{
    [DataMember] public int num;

    public Bla1(int id, int num) : base(id)
    {
        this.num = num;
    }
}


[DataContract]
public class Blubb
{
    [DataMember] public int ID;
    [DataMember] public string name;

    public Blubb(int id, string name)
    {
        this.ID = id;
        this.name = name;
    }
}

IService:

[Description("returns service's details")]
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)]
Blibla DoSomething();

Услуга:

public Blibla DoSomething()
{
    Message msg;
    DoHttpMethodTypeSpecific();

    Blibla bb = new Blibla(true);
    return bb;
}

РЕДАКТИРОВАТЬ

Ответ Авраама Цяня - это именно то, что я искал. Моя служба отвечает правильно сериализованным объектом Bla1.

{
    "__type":"Bla1",
    "id":22,
    "num":22
}

Если кто-то знает способ подавить автоматически добавленный "__type":"Bla1"
пожалуйста, дайте мне знать...

0
0
341
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В соответствии с вашей ошибкой и кодом я провел тест и обнаружил, что в классе Bla есть проблема с сериализацией. При передаче класса Bla WCF не смог распознать подкласс (Bla1) и способы их сериализации, поэтому мы должны добавить атрибут KnowType к базовому классу.

[DataContract]
[KnownType(typeof(Bla1))]
public class Bla
{
    [DataMember] public int id;
    public Bla(int id)
    {
        this.id = id;
    }
}

https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/data-contract-known-types

Пробовали ваше решение, но, к сожалению, ошибка не устранена.

Evaniar 05.11.2018 06:55

Мне очень жаль, что я дал неправильный ответ, потому что я неправильно понял ваш вопрос ранее. Я обновил свой ответ.

Abraham Qian 07.11.2018 09:13

Идеально. Раньше не слышал о KnowType. Есть ли способ подавить добавленное поле __type Bla1:#RFIDWebService.Lib? Наверное, нет, правда?

Evaniar 07.11.2018 09:53

Насколько мне известно, мы могли бы использовать метод атрибута DataContract (DataMember), чтобы указать имя поля и пространство имен. [DataContract (Namespace = "", Name = "bla1")]

Abraham Qian 07.11.2018 10:12

Посмотрите здесь для сериализации __type.

mike 28.03.2020 06:51

Другие вопросы по теме