Я немного плохо знаком с WCF и попытаюсь ясно описать то, что я пытаюсь сделать.
У меня есть веб-сервис WCF, который использует запросы JSON. Я в порядке, отправляя/получая JSON по большей части. Например, следующий код работает хорошо и как ожидалось.
JSON отправляется:
{ "guy": {"FirstName":"Dave"} }
WCF:
[DataContract]
public class SomeGuy
{
[DataMember]
public string FirstName { get; set; }
}
[OperationContract]
[WebInvoke(Method = "POST",
BodyStyle = WebMessageBodyStyle.WrappedRequest,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]
public string Register(SomeGuy guy)
{
return guy.FirstName;
}
Это возвращает объект JSON с "Dave" как ожидалось. Проблема состоит в том, что я не могу всегда гарантировать, что JSON, который я получаю, будет точно соответствовать участникам в моем DataContract. Например, JSON:
{ "guy": {"firstname":"Dave"} }
не сериализирует правильно, потому что случай не соответствует. парень. FirstName будет пустым. Это поведение имеет смысл, но я действительно не знаю, как обойти это. Я должен вызвать имена полей на клиенте или есть ли способ, которым я могу согласовать на стороне сервера?
Возможно связанный вопрос: я могу принять и сериализировать универсальный объект JSON в StringDictionary или некоторую простую структуру значения ключа? Таким образом независимо от того, что имена полей отправляются в JSON, я могу получить доступ к именам и значениям, которые были отправлены мне? Прямо сейчас единственный способ, которым я могу считать данные, которые я получаю, состоит в том, если это точно соответствует предопределенному DataContract.
Как следует из названия, контракт данных представляет собой набор правил. Если вы хотите надежно сопоставить сообщения с операциями, необходимо соблюдать эти правила.
Почему вы не можете гарантировать, что корпус будет правильным? Если вместо этого вы просто хотите использовать идентификаторы в нижнем регистре из JavaScript, вы можете использовать для этого атрибут MessageParameter
, но вам все равно нужно выбрать конкретное имя .
Теоретически вы можете принять необработанный JSON и десериализовать его вручную (просто возьмите строковый параметр и используйте любую библиотеку JSON для десериализации), но на самом деле это не в духе WCF.
Я думаю, что вам действительно нужно исправить не тот факт, что контракт данных чувствителен к регистру, а тот факт, что JSON не собирается правильно на стороне клиента.
Если вы хотите принять необработанную строку JSON в своей операции, измените BodyStyle
на WebMessageBodyStyle.Bare
и измените подпись метода, чтобы он принимал единственный строковый параметр, который будет заполнен любой строкой JSON, отправленной клиентом.
Обратите внимание, что все, что вы получаете, - это одна строка , из которой вы должны выполнять весь синтаксический анализ, сопоставление свойств, проверку и обработку ошибок. Я бы не пошел по этому пути, но если вы готовы взять на себя соответствующие усилия и риск, это один из возможных вариантов.
Вы можете попробовать добавить еще один атрибут DataMember
с именем в нижнем регистре, но я предполагаю, что вам нужен подход без учета регистра для согласования имен членов, и в этом случае использование дополнительных атрибутов DataMember становится нецелесообразным.
Вы могли бы предоставить реализацию IDataContractSurrogate , но для этого потребуется много дополнительной работы с вашей стороны, а также много размышлений (нет возможности сделать это статическим способом, который можно проверить во время компиляции).
Лично я отказался от использования класса DataContractSerializer
, когда дело касается JSON. Скорее, я использую Json.NET для всех моих потребностей JSON.Я вижу, где вы могли бы подключить Json.NET к DataContractSerializer
через IDataContractSurrogate
, но это все равно будет немного грубо.
Json.NET был легким выбором, учитывая сложность использования DataContractSerializer
. Кроме того, добавьте к тому факту, что DataContractSerializer
для JSON не обрабатывает значения DateTimeOffset
правильно, и для меня это не было проблемой, особенно с учетом того, что я работал в ASP. NET MVC (которая позволяет мне формировать результат так, как я хочу).
Это действительно лучший выбор, если вы предоставляете RESTful-сервисы с использованием JSON в качестве кодировки. Вы можете смешивать и сопоставлять это с WCF, чтобы предоставить все конечные точки по всем транспортным протоколам и протоколам сообщений, которые вам нужны.
Это действительно зависит от того, для чего вы используете данные. Теоретически вы можете сохранить этот общий тип, указав возвращаемый строковый тип. Однако данные будут представлять объект, и элемент управления на стороне клиента должен знать, как перечислить возвращаемый объект JSON. Вы можете вернуть тип, который также может помочь.
Затем в коде на стороне клиента вы можете иметь функцию, которая знает, как определять и читать различные типы.
Да, примеры см. на этой странице .
Отредактируйте
XPCOM и поэтому nsIFile
теперь являются устаревшими технологиями:
Использование
OS.File
является предпочтительным по сравнению с примерами в этой статье. Используйте эти устаревшие интерфейсы только в том случае, если OS.File недоступен.
Вы можете найти новый способ перейти здесь
-121--2853346-RequeyJS имеет инструмент оптимизации , который может объединить несколько файлов вместе, и он использует компилятор закрытия Google для выполнения minification/comment зачеркивания JavaScript. Инструмент оптимизации был основан на работе, которую я делал в системе Dojo build, но это то, что работает более автономно.
Отказ от ответственности: я разрабатываю требования JS
-121--4378539-Для достижения моей цели иметь сервис, который может принять совершенно произвольный список пар «key»: «value» в качестве сырой строки JSON, а затем решить, что делать с ними без необходимости знать имена «key» заранее, я объединил каспер и совет Аарона.
1-й, чтобы получить доступ к необработанному ряду JSON, этот блог MSDN был очень полезен.
Мне не удалось без проблем просто изменить параметр одного метода на String и BodyStyle
на WebStartBodyStyle.Bare
. При установке для BodyStyle значения Bare убедитесь, что для конечной точки behaviorConfiguration
задано значение < webHttp/>
, а не < enureWebScript/>
.
Второе замечание заключается в том, что, как указано в casperOne , метод может иметь только 1 параметр. Для доступа к исходному тексту (см. блог MSDN выше) этот параметр должен иметь значение Stream
.
Как только вы получите необработанную последовательность JSON, это просто вопрос десериализации ее в StringDictionary. Я выбрал JSON.Net для этого и это работает замечательно. Вот пример с голыми костями.
[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Bare,
ResponseFormat = WebMessageFormat.Json)]
public string Register(Stream rawJSON)
{
// Convert our raw JSON string into a key, value
StreamReader sr = new StreamReader(rawJSON);
Dictionary<string, string> registration =
JsonConvert.DeserializeObject<Dictionary<string, string>>(
sr.ReadToEnd());
// Loop through the fields we've been sent.
foreach (KeyValuePair<string, string> pair in registration)
{
switch (pair.Key.ToLower())
{
case "firstname":
return pair.Value;
break;
}
}
}
Это позволяет принять произвольный список полей через JSON и сделать имена полей нечувствительными к регистру. Я знаю, что это не самый строгий подход к целостности данных или к тому, как службы WCF идеально будут структурированы, но, насколько я могу судить, это самый простой способ добраться туда, куда я хочу пойти.