私は運が悪いので自分の問題の答えを探してグーグル検索してきましたので、他の誰かが私を助けてくれるかどうか試してみましょう。
いくつかの検証を行った後にユーザーを登録するWeb Api 2アクションがあります。すべてが機能する場合、シリアル化されたユーザーを返し、機能しない場合、BadRequest応答内で送信されるエラーメッセージを返します。
一方、私は応答のためにAPIを呼び出すWPFクライアントを持っています。
私の問題は、エラーによって送信された理由を取得できないことです。クライアントはBad Requestエラーメッセージを受け取るだけです。
これはコードの一部です:
Web APIアクション:
public async Task<IHttpActionResult> AddUser(NewUserDTO {
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (!model.IdCliente.HasValue)
{
ModelState.AddModelError("", "No existe el cliente");
return BadRequest(ModelState);
}
// do save stuff
return Ok(TheModelFactory.Create(user));
}
クライアント機能:
public async Task<ApplicationUserDTO> AddUser(NewUserDTO dto) {
using (var client = new HttpClient()) {
client.BaseAddress = new Uri(_urlBase);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Token);
HttpContent content = new StringContent(JsonConvert.SerializeObject(dto));
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpResponseMessage responseMessage = await client.PostAsync("api/accounts/AddUser", content);
if (responseMessage.IsSuccessStatusCode) {
var responseJson = await responseMessage.Content.ReadAsStringAsync();
user = JsonConvert.DeserializeObject<ApplicationUserDTO>(responseJson);
}
else
MessageBox.Show(responseMessage.Content.ReadAsStringAsync().Result);
return user;
}
}
誰でも手伝ってくれる?
編集:
DTO:
[Serializable]
public class NewUserDTO {
public int? IdCliente { get; set; }
[Required]
public string UserName { get; set; }
[Required]
public string Email { get; set; }
public string Role { get; set; }
public string Password { get; set; } }
とにかく... dtoはapi nutに正しく送信されます。ここでは、要求されたシリアル化されたdtoを示します。
"{\"IdCliente\":null,\"UserName\":\"Toni\",\"Email\":\"[email protected]\",\"Role\":\"Filtra\",\"Password\":\"TONI\"}"
最後に、私はあきらめました。たぶん、web.config、mvc config、api config、filteringなどのコードが原因で、コントローラーの場合とは異なり、コントローラーとは異なる応答が送信されます。ステータスコードとメッセージプロパティをDTOに追加し、常にオブジェクトを返しました。とにかく私を助けようとしたすべての人に感謝します。
Web.config httpErrorsセクションを確認しましたか?
私のweb.configが次のように見えたため、同じ問題が発生しました
<httpErrors errorMode="Custom" existingResponse="Replace">
<clear />
<error statusCode="404" path="~/Error/NotFound" responseMode="ExecuteURL" />
<error statusCode="403" path="~/Error/AccessDenied" responseMode="ExecuteURL" />
<error statusCode="500" path="~/Error/ServerError" responseMode="ExecuteURL" />
</httpErrors>
existingResponseがPassThroughに設定されていることを確認する必要があります
<httpErrors errorMode="Custom" existingResponse="PassThrough">
<clear />
<error statusCode="404" path="~/Error/NotFound" responseMode="ExecuteURL" />
<error statusCode="403" path="~/Error/AccessDenied" responseMode="ExecuteURL" />
<error statusCode="500" path="~/Error/ServerError" responseMode="ExecuteURL" />
</httpErrors>
それがあなたに役立つかどうかはわかりませんが、試してみてください。
return new BadRequestErrorMessageResult(yourErrorMessage);
var errorMessage = responseMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult();
MessageBox.Show(errorMessage);
それを返す代わりに、リクエスト例外をスローします。
throw new HttpResponseException(HttpStatusCode.BadRequest);
クライアントに詳細を渡す必要がない限り、Request.CreateErrorResponse
を返すことができますが、戻り値の型をHttpResponseMessage
に変更する必要があります。
RegisterメソッドのWebAPIConfig.csに以下の行を追加します。これには、一般的な500内部サーバーエラーだけでなく、エラーの詳細が含まれます。
GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;