У меня есть WS, который я называю так:
HttpResponseMessage response = await client.PostAsync(url, new StringContent(json));
WS выдаст исключение (запрещено), и в моем приложении Blazor, которое сделало вызов PostAsync, я получу HttpResponseMessage с кодом ответа 405, не уверен, почему это 405, должно быть 403 (Postman возвращает 403).
Я включил CORS (код Стек услуг):
Plugins.Add(new CorsFeature(allowedOrigins: "*",
allowedMethods: "GET, POST, PUT, DELETE, OPTIONS",
allowedHeaders: "*",
allowCredentials: true));
Это кое-что из Console.Writeline, которое я сделал непосредственно перед PostAsync:
Failed to load resource: the server responded with a status of 405 ()
** ОБНОВЛЕНО **
Это два метода:
public async Task<TResponse> PostAsync<TResponse, TRequest>(string requestUri, TRequest request)
{
string url = GetUrl(requestUri);
Console.WriteLine("URI: " + url);
string json = JsonConvert.SerializeObject(request);
Console.WriteLine($"{url} | {json}");
HttpResponseMessage response = await client.PostAsync(url, new StringContent(json));
return await GetResponseOrThrowHttpException<TResponse>(response);
}
private async Task<T> GetResponseOrThrowHttpException<T>(HttpResponseMessage response)
{
Console.WriteLine($"GetResponseOrThrowHttpException: {response.StatusCode}");
string responseString = await response.Content.ReadAsStringAsync();
Console.WriteLine($"GetResponseOrThrowHttpException ContentStringResult: |{responseString}|");
if (!response.IsSuccessStatusCode)
{
Newtonsoft.Json.Linq.JObject jsonObject = Newtonsoft.Json.Linq.JObject.Parse(responseString);
string responseStatusString = jsonObject["ResponseStatus"].ToString();
Console.WriteLine($"GetResponseOrThrowHttpException 4: {responseStatusString}");
ResponseStatus responseStatus = JsonConvert.DeserializeObject<ResponseStatus>(responseStatusString);
Console.WriteLine($"Throwing HttpException: {response.StatusCode} {responseStatus.Message}");
throw new HttpException(response.StatusCode, responseStatus.Message);
}
return JsonConvert.DeserializeObject<T>(responseString);
}
Когда я пытаюсь получить строковое значение ответа, оно пустое:
string responseString = await response.Content.ReadAsStringAsync();
а responseString — пустая (длина 0) строка.
Если я запускаю тот же самый запрос в Postman, я получаю правильный ответ:
Итак, ответ JSON, показанный внизу на изображении выше, — это то, с чем я хочу работать в приложении Blazor, анализировать его как объект JSON и двигаться дальше. Я также отмечаю, что здесь я получаю ошибку 403, которую я ожидал, а в приложении Blazor я получаю 405.
Является ли это проблемой CORS, хотя я включил CORS на стороне WS?
Да, интересно с 405. Я обновил ответ, немного больше кода и console.writelines, а также URL-адреса (немного замаскированные). Они одинаковы, и оба являются POST. CORS включен, я получаю ожидаемое исключение в WS.
Кажется, в вашем запросе почтальона много заголовков, они случайно не нужны для вашего запроса на сервере? Я не вижу, чтобы ты их добавлял
Хм, в Postman есть 8 автоматически добавленных заголовков, которые я не могу удалить. Однако в обоих случаях через postman или Blazor на сервер выбрасывается одно и то же исключение (которое я ожидаю и хочу), поэтому запрос доходит до одного и того же. Сообщение об ошибке «версия din....» также является тем, что я генерирую на стороне WS, поэтому оно ведет себя так же, как и WS. 8 автоматически добавленных заголовков не имеют отношения к WS.
О, Почтальон говорит: «Эти заголовки автоматически генерируются Почтальоном и не сохраняются по вашему запросу» :-)
Хорошо, кажется, что DTO (объект входа) неверен при отправке из Blazor (все свойства равны NULL), но в Postman они в порядке. Вероятно, это проблема.
Понял - это отсутствующий тип контента в приложении Blazor. По умолчанию он был обычным/текстовым, хотя должен был быть application/json





Убедитесь, что вы настроили правильную конфигурацию CORS для домена.
Похоже, вы вызвали другую комбинацию domain:port из своего приложения Blazor. Даже если это C#, все правила безопасности внутри браузера остаются в силе.
Спасибо, CORS настроен и работает. У меня есть другие запросы, которые разрешены и работают нормально (до этого теста входа в систему).
Вы можете запустить Fiddler и проверить, что на самом деле отправляется на сервер? Таким образом, вы действительно увидите, какой ответ произойдет? Ничего особенного для Blazor, те же правила, что и для JS fetch. Весьма вероятно, что это все еще проблема CORS, другая альтернатива заключается в том, что вы не можете прочитать ответ содержимого, если сервер возвращает 405, и это именно тот ответ, который вы хотите получить. Если вы не ожидаете 405, тогда ищите CORS.
Я ожидаю 403, а не 405... Почтальон возвращает мне 403, но приложение Blazor возвращает мне 405.
Хорошо, кажется, что DTO (объект входа) неверен при отправке из Blazor (все свойства равны NULL), но в Postman они в порядке. Вероятно, это проблема.
Вы вели меня в правильном направлении; это был "Content-Type" =) по умолчанию plain/text вместо требуемого application/json. Это создало 405. Если вы предпочитаете, создайте ответ на это =)
Я думаю, ваш контент должен быть размещен так:
new StringContent(json, Encoding.UTF8, "application/json")
Даже если это не причина ваших страданий, лучше использовать это так...
Надеюсь это поможет...
Да, JohnChris и codevision привели меня в правильном направлении, и я понял это. Спасибо =)
Вы могли бы использовать метод расширения Blazor public static Task<T> PostJsonAsync<T> (этот HttpClient httpClient, строка requestUri, содержимое объекта), что могло бы избавить вас от этой головной боли.
Спасибо. Да, я знаю об этом, но почему-то сейчас не могу вспомнить, я решил не использовать его, или он не работал... или что-то в этом роде... Не могу вспомнить =)
код состояния 405: метод не разрешен, это указывает на то, что, возможно, то, что вы считаете одинаковым, не так, не могли бы вы отладить и опубликовать то, что находится в
urlиjsonв вашемPostAsync