WCF отвечает HTTP 400 на сериализованную строку JSON из приложения Razor Pages - PullRequest
0 голосов
/ 28 марта 2019

Я пытаюсь отправить запрос, содержащий JSON, из приложения Razor Pages в конечную точку службы WCF, ожидая Json WebMessageFormat и Bare BodyStyle. JSON проходит нормально через Postman, но не когда я отправляю его через http-клиент. Wireshark также показывает некоторые дополнительные байты вокруг JSON в пакете, созданном http-клиентом, которых нет в пакете Postman. Wireshark также сообщает об этом как line-based text data: application/json для пакета Postman. Пакет .Net: JavaScript Object Notation: application/json.

Вот мой код C # для отправки JSON на конечную точку WCF:

var client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:8000");

dynamic foo = new ExpandoObject();
foo.position = 1;

var content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(foo), System.Text.Encoding.UTF8, "application/json");

var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost:8000/WCFService/ControllerV1/PostJSON");
request.Headers.Add("cache-control", "no-cache");
request.Headers.Add("Accept", "*/*");
request.Headers.Add("Connection", "keep-alive");
request.Content = content;


try
{
    var response = await client.SendAsync(request);
    response.EnsureSuccessStatusCode();
    string responseBody = await response.Content.ReadAsStringAsync();
}
    catch (HttpRequestException e)
{
    Console.WriteLine(e.Message);
}

А вот мое объявление конечной точки WCF:

[OperationContract, WebInvoke(Method="POST", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
void PostJSON(string jsonString);

Я ожидаю, что пакеты будут выдавать один и тот же ответ от сервера, но то, что выглядит как одна и та же строка, создает ответ 200, когда пакет создается почтальоном, и ответ 400, когда он создается .Net. Я явно упускаю что-то тонкое здесь, но, похоже, я не могу этого дразнить.

1 Ответ

0 голосов
/ 28 марта 2019

Есть 2 возможных BodyStyle для запроса и ответа, завернутый или голый . Когда вы указываете упакованный стиль тела, служба WCF ожидает, что будет передан действительный json, который в вашем случае будет

//note that property name is case sensitive and must match service parameter name
{
    "jsonString": "some value"
}

И когда вы указываете голый формат, служба ожидает только простое строковое значение (в случае типа примитива, как у вас) в качестве запроса, подобного этому

"some value"

Когда вы сериализуете свой объект, как это

dynamic foo = new ExpandoObject();
foo.position = 1;

string result = JsonConvert.SerializeObject(foo);

result содержит следующий json

{
    "position":1
}

, что соответствует формату , и служба возвращает 400: Bad Request. Все, что вам нужно сделать, это превратить этот JSON в действительное значение JSON string, как это

"{\"position\":1}"

Это можно сделать повторным JsonConvert.SerializeObject вызовом

.
dynamic foo = new ExpandoObject();
foo.position = 1;

string wrapped = JsonConvert.SerializeObject(foo);
string bare = JsonConvert.SerializeObject(wrapped);
var content = new StringContent(bare, System.Text.Encoding.UTF8, "application/json");
...