Ответ 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 для вызова службы, но так, как вы задавали этот вопрос, похоже, что вы этого не хотите.