Редактировать неверный запрос

#c# #controller #request #asp.net-core

#c# #контроллер #запрос #asp.net-ядро

Вопрос:

У меня есть объект ответа, который я хочу вернуть пользователю, если в контроллере возникнет исключение. Однако, когда я пытаюсь отправить обратно BadRequest, я, похоже, не могу отправить обратно свой объект ответа. Итак, мой вопрос в том, как мне отредактировать BadRequst, чтобы он содержал мой объект ответа и / или как мне отправить обратно мой объект ответа с кодом состояния ошибки?

Контроллер

 public async Task<IActionResult> Login([FromBody] LoginViewModel model) {
    Response response = new Response(); 
    try {
        if (ModelState.IsValid) {
            var result = await signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
            if (result.Succeeded) {
                logger.LogInformation(1, "User logged in.");
                return Json("User logged in.");
            }
            if (result.RequiresTwoFactor) {
                response.id = 1 ; 
                throw new LoginException("Login requiest two factor", new InvalidOperationException());
            }
            if (result.IsLockedOut) {
                response.id = 2 ; 
                logger.LogWarning(2, "User account locked out.");
                throw new LoginException("User account locked out", new InvalidOperationException());
            }
            else {
                response.id = 3 ; 
                throw new LoginException("Invalid login attempt", new InvalidOperationException());
            }
        }
        response.id = 4 ; 
        var modelErrors = ModelState.Values.ToList(); 
        throw new LoginException("Model State Error", ModelState, new InvalidOperationException());
    } catch (LoginException ex){
        return BadRequest(response); // response with status: 400 Bad Request for URL, no response object is in here. 
    }
}
  

Интерфейс

 login(email:any, password:any, remember:any){
    //let body:User = {email:email, password:password}; 
    let headers = new Headers({ 'Content-Type': 'application/json' });

    let body = {Email:email, Password:password,RememberMe:false }; 
    console.log(body); 
    this.http.post('/api/Account/Login', body ,{headers:headers})
    .map(response  => response.json())
    .subscribe(
         response => { 
             console.log("Success !!!:n" response); 
             this.router.navigate(['/home']);
        }, 
        error => {
             console.log("Error !!!:n" error); 
        }
    );
}
  

Комментарии:

1. Как определяется класс BadRequest? Кроме того, я предлагаю вместо того, чтобы выбрасывать исключения и немедленно перехватывать их, вы просто возвращаете свой BadRequest (ответ).

2. BadRequest — это вспомогательный метод класса контроллера, и он уже подразумевает код состояния: HTTP Code 400 (BadRequest), отсюда и название. Также вы не должны создавать исключение в контроллере, но возвращать IActionResult. Вы злоупотребляете исключениями для генерации результатов ошибок. Исключения — это то, о чем говорит название: исключительные ошибки. Блокировка пользователя или проверка ввода не являются исключительными, но ожидаемыми

Ответ №1:

Не совсем понятно, о чем вы спрашиваете?

Вы хотите вернуть только код состояния 400? Используйте версию без параметров return BadRequest()

Хотите другой код состояния? Используйте другой метод. BadRequest имеет имя с помощью HTTP Statuscode 400 (BadRequest). Если вы хотите самостоятельно установить код состояния, используйте return Status(HttpStatusCode.Unauthorized); or что угодно.

Хотите вернуть сообщение об ошибке в формате json? Для этого используйте классы ошибок или анонимный класс:

 return BadRequest(new { ErrorMessage = "Account is locked." });
  

Но что бы вы ни хотели сделать, выбрасывать исключения в контроллере неправильно. Действие контроллера НИКОГДА не должно вызывать исключение. Также, как указано в комментариях, исключения должны использоваться для исключительных случаев. Неправильный пароль, заблокированный пользователь или неправильный метод аутентификации (т. Е. Отсутствие двухфакторной аутентификации, когда это требуется) являются ожидаемыми ошибками и не должны обрабатываться с помощью исключений.

Исключения (только когда они генерируются) по своей сути являются дорогостоящими операциями в компьютерной программе. По этой причине Microsoft внедрила IdentityResult класс для возврата списка ожидаемых ошибок, а не для создания исключений во время вызова signInManager.PasswordSignInAsync

Комментарии:

1. вернуть неверный запрос(новый { ErrorMessage = «Учетная запись заблокирована».});. В конолсе я не вижу сообщения о блокировке учетной записи. Но это именно то, что я пытаюсь сделать. В консоли написано Ошибка!!!: Ответ со статусом: 400 Неверный запрос URL: localhost:5000/api/ Account/Login »

2. Он не печатает его в журнале, его то, что возвращается в браузер

3. Итак, как мне получить сообщение из браузера?

4. Зависит от того, как вы его используете. Если у вас есть клиент javascript, проанализируйте его и покажите пользователю. Если вы используете клиент .NET или Java, сделайте то же самое там. Это то, что возвращает служба rest. То, что потребитель делает с этим, зависит от потребителя. Вы когда-нибудь раньше работали с веб-технологиями? Кажется, у вас странные ожидания от того, как это работает

5. Да, я использую angular в интерфейсе. Отображаемый ответ json является ошибкой!!!: Ответ со статусом: 400 Неверный запрос URL: localhost:5000/api/ Account/Login » …. Нет объекта ErrorMessage.

Ответ №2:

Вместо возврата IActionResult , почему бы вам не вернуть a HttpResponseMessage , а затем вы можете сделать что-то вроде: return Request.CreateResponse(System.Net.HttpStatusCode.BadRequest)