Как вызвать wcf restful службы из Fiddler по запросу JSON? - PullRequest
7 голосов
/ 14 августа 2011

Я новичок в wcf.Я не мог найти проблему, которая была, почему мой спокойный сервис wcf выдает «неверный запрос».Я использую .NET 4.0.

Мой сервис:

[OperationContract(Name="Add")]
[WebInvoke(UriTemplate = "test/", Method = "POST",
          ResponseFormat=WebMessageFormat.Json,
          RequestFormat=WebMessageFormat.Json )]
public int Add(Number n1)
{
    res = Convert.ToInt32(n1.Number1) + Convert.ToInt32(n1.Number2);
    return res;
}

Данные: ..

[Serializable]
    public class Number
    {
        public int Number1 { get; set; }
        public int Number2 { get; set; }
    }

Когда я звоню из фиддлера, он возвращает 'HTTP / 1.1 400 Bad Request'

Мой заголовок запроса фиддлера:

User-Agent: Fiddler
Host: localhost:4217
Content-Type: application/json; charset=utf-8

И тело запроса:

{"Number1":"7","Number2":"7"}

И заголовок ответа:

HTTP/1.1 400 Bad Request
Server: ASP.NET Development Server/10.0.0.0
Date: Sun, 14 Aug 2011 18:10:21 GMT
X-AspNet-Version: 4.0.30319
Content-Length: 5450
Cache-Control: private
Content-Type: text/html
Connection: Close

Но если я вызываю эту службу клиентской программой C #, это нормально.

Мой код клиента:

uri = "http://localhost:4217/Service1.svc/";
Number obj = new Number() { Number1 = 7, Number2 = 7 };
using (HttpResponseMessage response = new HttpClient().Post(uri+"test/",
       HttpContentExtensions.CreateDataContract(obj)))
{
    string res = response.Content.ReadAsString();
    return res.ToString();
}

, пожалуйста, помогите мне ........

Спасибо.

Ответы [ 2 ]

8 голосов
/ 15 августа 2011

Чтобы выяснить проблему с вашим кодом, нужно включить трассировку на сервере, и возникнет исключение, объясняющее проблему. Я написал простой тест с вашим кодом, и в нем была похожая ошибка (400), а в трассировках была следующая ошибка:

The data contract type 'WcfForums.StackOverflow_7058942+Number' cannot be
deserialized because the required data members '<Number1>k__BackingField,
<Number2>k__BackingField' were not found.

Типы данных, отмеченные [Serializable], сериализуют все поля в объекте, а не свойства . Закомментировав этот атрибут, код на самом деле работает нормально (тип затем попадает в правило «POCO» (Plain Old Clr Object), которое сериализует все открытые поля и свойства.

public class StackOverflow_7058942
{
    //[Serializable]
    public class Number
    {
        public int Number1 { get; set; }
        public int Number2 { get; set; }
    }
    [ServiceContract]
    public class Service
    {
        [OperationContract(Name = "Add")]
        [WebInvoke(UriTemplate = "test/", Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
        public int Add(Number n1)
        {
            int res = Convert.ToInt32(n1.Number1) + Convert.ToInt32(n1.Number2);
            return res;
        }
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        host.AddServiceEndpoint(typeof(Service), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());
        host.Open();
        Console.WriteLine("Host opened");

        WebClient c = new WebClient();
        c.Headers[HttpRequestHeader.ContentType] = "application/json; charset=utf-8";
        c.Encoding = Encoding.UTF8;
        Console.WriteLine(c.UploadString(baseAddress + "/test/", "{\"Number1\":\"7\",\"Number2\":\"7\"}"));

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}
2 голосов
/ 15 августа 2011

Одна вещь, которую вы делаете неправильно - это формат объекта запроса. Измените это на:

{ n1: { "Number1":"7","Number2":"7"} }

Имена параметров - это имена корневых свойств объекта json, переданные конечной точке wcf json.

У меня есть пример службы wcf на git. Помимо прочего, он имеет конечную точку json, а в Default.asmx я использую jquery для вызова. Я бы посоветовал вам создать аналогичную веб-страницу (разместить ее на том же веб-сайте, что и служба WCF), которая вызывает вашу службу json через jquery, и протестировать ее с ней во время работы fiddler, чтобы получить пример запроса. Это будет проще и менее подвержено ошибкам, чем самостоятельное построение запроса, поскольку jquery позаботится о многих деталях в заголовке.

Пример jjery ajax-кода для вызова моего эхо-сервиса, который вы можете адаптировать для своего сервиса, выглядит следующим образом:

    $("#btnEchoString").click(function () {
        var request = $("#request");
        var response = $("#response");
        $.ajax({
            url: 'EchoService.svc/JSON/Echo',
            type: "POST",
            contentType: "application/json; charset=utf-8",
            data: JSON.stringify({ request: request.val() }),
            dataType: "json",
            success: function (data) {
                response.val(data.d);
            },
            error: function (request, status, error) {
                //TODO: do something here
            }
        });
    });
...