Как получить WCF DataContract с динамическим членом json

в проекте, над которым я работаю, у нас есть требование иметь DataContract, который может содержать какой-то неопределенный JSON.

DataMember - это некий JSON, который имеет смысл только для клиента. Мы хотим, чтобы клиент отправил нам json, о котором мы не знаем.

Пример:

public class Contract
{
    [DataMember]
    public int clientId;
    [DataMember]
    public string json;
}

Очевидно, что для определения такого контракта клиенту потребуется экранировать json следующим образом:

{
    "clientId":1,
    "json": "{\"test\":\"json\"}"
}

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

{
    "clientId":1,
    "json": {"test":"json"}
}

Возможные решения мы исследовали:

использовать Stream в качестве параметров контракта для запросас телом. Работает, но ставит работу на нашу сторону вместо использования фреймворка.ОпределяющийJSON» как DynamicObject. Не работает. Не удалось получить собственность написана правильно.Используя библиотеку Newtonsoft, измените сериализатор контракта по умолчанию в конечной точке WCF, чтобы сериализовать все входные данные в объект JObject. Мы также обрабатываем сериализацию по запросу, и это вызывает проблемы в нашем приложении. Мы'Я предпочел бы избежать этого пути.

У кого-нибудь есть возможное решение этой проблемы?

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

Сервис предлагает отдых на ресурсах JSON. Он определяет одну конечную точку с помощью webHttpBinding. Операция определяется следующим образом (для простоты выделено):

[WebInvoke(Method = "POST", UriTemplate = "...", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
[OperationContract]
Stream Create(Contract c);

Также сервис украшен следующим атрибутом:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]

Спасибо. JF

 Jean-Francois16 окт. 2012 г., 17:15
@Sixto Saez: мы не предлагаем мыло. У нас есть 1 конечная точка с webHttpBinding для поддержки только REST json.
 Igarioshka16 окт. 2012 г., 17:56
Вы будете использовать тот неопределенный JSON, который клиент отправил в запросе?
 Sixto Saez16 окт. 2012 г., 16:50
Похоже, ваш клиент использует ваш сервис в виде мыла / XML, и выпытается туннелировать строки JSON через мыльное сообщение. Рассматривали ли вы сохранение отдельных конечных точек для мыла / XML и ответа JSON. Вы можете сохранить стандартную конечную точку DataContact в текущей привязке как есть и добавить новуюWebHttpBinding конечная точка для ответа строкой JSON. Да, это добавляет вызов, но этоУпростим ваши контракты.

Ответы на вопрос(5)

вы хотите, чтобы она содержала объект. Как это:

public class Contract
{
    [DataMember]
    public int clientId;
    [DataMember]
    public JsonObj json;
}
public class JsonObj
{
    [,DataMember]
    public string test;
}

Таким образом, парсер json выведет то, что вам нужно. Я надеюсь, что я ясно дал понять.

Ура!

 Jean-Francois16 окт. 2012 г., 19:41
К сожалению, это победилоне делай этого. Для клиента это будет работать, но другой может опубликовать совершенно другой JSON. некоторые как: {"ID клиента": 1 "JSON»: {"Я бы": 13 "исх «:»другой"}}

Измените подпись, чтобы принять поток. например:

public String ProcessJson(Stream jsondata)
{
//play with jsondata

}

Для получения в виде потока переопределите методы WebContentTypeMapper.

 public class RawWebContentTypeMapper : WebContentTypeMapper 
    {
        public override WebContentFormat GetMessageFormatForContentType(string contentType)
        {            
                return WebContentFormat.Raw;       
        }   
    }
Решение Вопроса

SON как части контракта на данные. Вы'Мне нужно будет использовать другой сериализатор, который делает это - JSON.NET - тот, который мне лично нравится. Чтобы иметь возможность изменить сериализатор, вы можете использовать другой форматер сообщений, и в посте наhttp://blogs.msdn.com/b/carlosfigueira/archive/2011/05/03/wcf-extensibility-message-formatters.aspx У меня есть пример, который делает именно это - заменяет сериализацию по умолчанию, используемую WCF, на JSON.NET.

Обратите внимание, что для получения произвольного JSON с использованием этой библиотеки выВам нужно будет изменить тип "JSON» Свойство, эквивалентное произвольному JSON в JSON.NET, JToken:

public class Contract 
{ 
    [DataMember] 
    public int clientId; 
    [DataMember] 
    public Newtonsoft.Json.Linq.JToken json; 
} 
 Jean-Francois19 окт. 2012 г., 20:36
Привет, Карлос, я много раз заглядывал в твой блог на предмет своей проблемы еще до того, как задал вопрос ;) Я уже пробовал этот маршрут, внедряя свой собственный форматер сообщений, но это влечет за собой некоторые проблемы в нашем приложении. Я'Я хотел бы найти другой путь, если это возможно. В противном случае яв конечном итоге меняем форматер. Кстати, спасибо за ваш блог, я прочитал много ваших сообщений о расширяемости WCF за последние месяцы.

сса

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class xxx {...}

До реализации метода

[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)]
public Contract getContract() {...}
 SamuGG16 окт. 2012 г., 17:44
Обратным путём к этому может быть объявление свойства вашего класса с именем 'JSON» как объект вместо строки. Этот объект должен быть классом, включающим одно уникальное свойство: public string test {get; set;}
 Jean-Francois16 окт. 2012 г., 17:15
атрибут AspNetCompatibilityRequirements находится в нашем экземпляре контракта, а операция украшена [OperationContract] и [WebInvoke (Method = "СООБЩЕНИЕ" UriTemplate =»....», ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare

Вы пробовали это?

public class Contract 
{ 
    [DataMember] 
    public int clientId; 
    [DataMember] 
    public Dictionary DynamicProperties; 
}
 Tomer W01 янв. 2017 г., 16:16
это дало бы только плоские объекты ... думать о{students:[{name:"john", grade:54},{name:"michelle", grade:95}], class:"Eco 1o1"}

Ваш ответ на вопрос