Передача сложных объектов в службу отдыха WCF

У меня есть Операционный контракт, который принимает сложный объект, и я вызываю операцию через jQuery. Как передать объект сложного типа, например, с помощью jQuery. Ниже приведена подпись операции:

public Resolution CreateNewResolution(Resolution NewResolution);

Мне нужно передать объект Resolution на клиенте, но я не знаю, как сделать что-то вроде jQuery. Любая помощь?

Спасибо

Ответ 1

Посмотрите сообщение Denny для начала, хотя я не согласен с его использованием GET и передаю JSON в querystring для сложных параметров, Это кажется действительно неправильным.


Параметр, который вы используете для data, представляет собой json-представление любого вашего типа разрешения. Например, предположим, что тип и операция определены на стороне сервера следующим образом:

[DataContract( Namespace = "urn:brandon.michael.hunter/ws/2010/01", 
               Name = "Resolution" )]
public class Resolution
{
    [DataMember( IsRequired = true, Name = "Name" )]
    public string Name     { get; set; } 

    [DataMember( IsRequired = true, Name = "Rank" )]
    public int Rank { get; set; }

    [DataMember( IsRequired = true, Name = "SerialNumber" )]
    public int SerialNumber { get; set; } 

    [DataMember( IsRequired = false, Name = "Id" )]
    public int Id { get; set; } 
}

[OperationContract]
[WebInvoke(Method = "PUT",
           RequestFormat=WebMessageFormat.Json,
           ResponseFormat = WebMessageFormat.Json,
           UriTemplate = "new")]
public Resolution CreateNewResolution(Resolution r)
{
    // your logic here
    r.Id = System.Guid.NewGuid();
    return r;
}

Затем в Javascript код, который вы используете, может выглядеть так:

var resolution = {r: { Name : "Fred", Rank : 2,  SerialNumber : 17268 }};

// convert object to JSON string  (See http://jollytoad.googlepages.com/json.js)
var objectAsJson = $.toJSON(resolution);
// result is a string:  '{"Name":"Fred","Rank":"2","SerialNumber":"17268"}'

$.ajax({
  type        : "PUT",              // must match Method in WebInvoke
  contentType : "application/json",
  url         : "Service.svc/new",  // must match UriTemplate in WebInvoke
  data        : objectAsJson, 
  dataFilter  : function (data, type) {
      // convert from "\/Date(nnnn)\/" to "new Date(nnnn)"
      return data.replace(/"\\\/(Date\([0-9-]+\))\\\/"/gi, 'new $1');
  },
  processData : false,              // do not convert outbound data to string (already done)
  success     : function(msg){ ... },
  error       : function(xhr, textStatus, errorThrown){ ... } 
 });

Примечания:

  • Вам нужно, чтобы имя переменной (r) было первым объектом в передаваемом JSON, по крайней мере с WCF 4. Когда я использовал предыдущий пример, это не сработало, пока я не вставил имя переменной в начале.
  • Для передачи сложных объектов в JSON используйте PUT или POST в качестве типа (HTTP-метод) запроса
  • вам нужно преобразовать сложный объект в строку JSON. Там хороший, крошечный плагин jquery для этого. Denny предоставляет свою собственную реализацию.
  • Я обнаружил, что если я использую processData=true, то полученная строка, отправленная службе, находится в формате запроса, а не в JSON. Не то, что я хочу для передачи сложных объектов. Поэтому я установил значение false. Использование true было бы хорошо для более простых запросов, отличных от JSON, где вы делаете WebGet, и все параметры находятся в строке запроса.
  • dataFilter позволяет корректно десериализовать объекты DateTime
  • Параметр msg, переданный в обратный вызов успеха, содержит возвращенный json.
  • Вы можете использовать URL-ретранслятор, чтобы скрыть этот тег .svc в URL-адресе запроса
  • в этом случае служба WCF использует поведение webHttp, а не enableWebScript. Последний динамически генерирует прокси-серверы Javascript для вызова службы, но так, как вы задавали этот вопрос, похоже, что вы этого не хотите.

Ответ 2

Ознакомьтесь с блоком Gil Fink относительно объединения служб данных WCF, JSONP и jQuery

http://blogs.microsoft.co.il/blogs/gilf/archive/2011/04/24/combining-wcf-data-services-jsonp-and-jquery.aspx

Во время Mike Flaskos сеанс в MIX11 он показал, как создать JSONP, известную службу данных WCF, с атрибутом JSONPSupportBehavior, доступным для загрузить из галереи кода MSDN (и предполагается, что это часть пространства имен Microsoft.Data.Services.Extensions). В этом столбце Ill показан простой пример, который использует атрибут и jQuery, чтобы сделать перекрестный вызов JSONP для службы данных WCF.

Настройка среды

Сначала я начал с создания двух разных веб-приложений ASP.NET. Первое приложение включает вызывающую страницу, а вторая включает в себя службу данных WCF. Затем во втором веб-приложении я создал модель модели Entity Framework и службу данных WCF с этой модели. Я также добавил класс JSONPSupportBehavior.cs, который существует в ссылка, которую я поставил ранее. Класс включает реализацию JSONPSupportBehavior, которая реализует интерфейс WCF IDispatchMessageInspector. Также он включает JSONPSupportBehaviorAttribute, который я использую в своем коде. Код прост и выглядит следующим образом:

[JSONPSupportBehavior] 
public class SchoolDataService : DataService<SchoolEntities>
{
  // This method is called only once to initialize service-wide policies.
  public static void InitializeService(DataServiceConfiguration config)
  {      
    config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);      
    config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
  }
}

Выполнение вызова JSONP

Во втором веб-приложении Ive создала веб-форму, которая будет содержать пример вызова JSONP. Вот код, который делает вызов:

<!DOCTYPE html>
<html>
<head runat="server">
    <title>JSONP Call</title>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.1.js" type="text/javascript"></script>
</head>
<body>
    <form id="form1" runat="server">
    <output id="result">
    </output>
    </form>
    <script type="text/javascript">
        $.getJSON('http://localhost:23330/SchoolDataService.svc/Courses?$format=json&$callback=?', 
        function (response) { 
            $.each(response.d, function (index, value) {
                var div = document.createElement('div');
                div.innerHTML = value.Title;
                $('#result').append(div);
            })
        });        
    </script>
</body>
</html>

Давайте рассмотрим код веб-формы: Сначала я использую Microsoft CDN для извлечения библиотеки jQuery. Затем Ive создал выходной элемент HTML5, чтобы добавить к нему вывод вызова. В основном script я использую функцию jQuerys getJSON, которая вызывает службу данных WCF. Обратите внимание, что для получения ответа JSON от службы данных WCF вам необходимо использовать параметр строки $format = json query. После получения данных я повторяю и создаю элемент div для каждого полученного заголовка. Это делается в функции успеха, которую я подключил в вызове функции getJSON. Вот результат запуска кода:

enter image description here

Резюме

В сообщении я поставил простой пример вызова JSONP в службу данных WCF с помощью jQuery. Такое решение может помочь вам использовать службы данных WCF, существующие в других доменах с вашей стороны. В последующем сообщении Ill показан тот же пример, используя новую библиотеку datajs