2014-04-15 13 views
13

Buduję aplikację AngularJS SPA z WebApi dla zaplecza. Używam atrybutów do sprawdzania poprawności modelu na serwerze, jeśli sprawdzanie poprawności nie powiedzie się, to właśnie zwracam z ModelState.Jak renderować błędy do klienta? AngularJS/WebApi ModelState

 {"Message":"The request is invalid.","ModelState":{"model.LastName":["Last Name must be at least 2 characters long."]}} 

Jak mogę to uczynić klientowi z AngularJS?

 //Save User Info 
    $scope.processDriverForm = function(isValid) { 
     if (isValid) { 
      //set button disabled, icon, text 
      $scope.locked = true; 
      $scope.icon = 'fa fa-spinner fa-spin'; 
      $scope.buttonText = 'Saving...'; 
      $scope.submitted = true; 
      $scope.formData.birthDate = $scope.formData.birthMonth + '/' + $scope.formData.birthDay + '/' + $scope.formData.birthYear; 
      $http({ 
        method: 'POST', 
        url: 'api/Account/Register', 
        data: $.param($scope.formData), 
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' } // set the headers so angular passing info as form data (not request payload) 
       }) 
       .success(function (data) { 
        console.log(data); 
        toastr.success('User ' + $scope.formData.username + ' created!'); 
        $scope.userForm.$setPristine(); 
        $scope.formData = {}; 
        //reset the button 
        $scope.locked = false; 
        $scope.icon = ''; 
        $scope.buttonText = 'Save'; 
        //reset validation submitted 
        $scope.submitted = false; 
       }) 
       .error(function (data, response) { 
        console.log(data); 
        toastr.error('Ooops! There was an error creating the user. Try again and if the problem persists, contact Support.'); 
        //reset the button 
        $scope.locked = false; 
        $scope.icon = ''; 
        $scope.buttonText = 'Save'; 
        $scope.submitted = false; 

        var resp = {}; 

        var errors = []; 
        for (var key in resp.ModelState) { 
         for (var i = 0; i < resp.ModelState[key].length; i++) { 
          errors.push(resp.ModelState[key][i]); 
         } 
        } 
        $scope.errors = errors; 

       }); 

     } 
     else { 
      toastr.warning('Invalid User Form, correct errors and try again.'); 
     } 
    }; 
+0

co próbowaliście? Możesz sobie z tym poradzić kilkadziesiąt metod. To pytanie jest szerokie. Najpierw musisz wybrać zachowanie aplikacji, aby je rozesłać (powiadomienie? Popup? Przyklejone powiadomienie?) ... –

+0

Niestety, nie chciałem sposobu renderowania. Po prostu nie byłem pewien, jak uzyskać błędy z tablicy ModelState, która jest przekazywana z błędem 400 BadRequest –

Odpowiedz

15

Dokonując połączenia z serwerem, uchwycić błąd w oparciu o odrzuceniu obietnicy $http.

Następnie w kontrolerze Proponuję spłaszczenie odpowiedzi na szereg błędów upon obsługi błędu na wyświetlaczu, jak pokazano w tym fiddle example:

for (var key in resp.ModelState) { 
    for (var i = 0; i < resp.ModelState[key].length; i++) { 
     errors.push(resp.ModelState[key][i]); 
    } 
} 

Aby umieścić to wszystko razem:

// Post the data to the web api/service 
$http.post(url, data) 
    .success(successHandler) 
    .error(function (response) { 
     // when there's an error, parse the error 
     // and set it to the scope (for binding) 
     $scope.errors = parseErrors(response); 
    }); 

//separate method for parsing errors into a single flat array 
function parseErrors(response) { 
    var errors = []; 
    for (var key in response.ModelState) { 
     for (var i = 0; i < response.ModelState[key].length; i++) { 
      errors.push(response.ModelState[key][i]); 
     } 
    } 
    return errors; 
} 
+0

Dodałem żądanie $ http w moim kodzie, ale jak mogę uzyskać te błędy z BadRequest, który jest zwracany i umieścić w zmiennej "resp". Wciąż jestem na wczesnym etapie nauki JS, zaledwie 2 miesiące temu i to moja pierwsza ekspozycja na JS i AngularJS. Czy to właśnie jest .push? –

+0

Zaktualizowałem kod w mojej odpowiedzi, aby pokazać bardziej kompletne rozwiązanie. – Brocco

+0

Dobrze jest iść i teraz rozumiem ten proces. Świetna sprawa. –

3

Najprostszym sposobem może być pobranie wszystkich błędów z ModelState i umieszczenie ich w nowej właściwości w $ scope.

$http.post(url, data). 
    success(successHandler). 
    error(function (response) { 
     $scope.errors = getErrors(response); 
    }); 

function getErrors(responseWithModelState) { 
    var errors = []; 
    /* 
    Get error messages out of ModelState property, and push them into the errors variable... 
    Brocco beat me to it. :-) 
    */ 
    return errors; 
}; 

Następnie w HTML ...

<ul> 
    <li ng-repeat="e in errors">{{e}}</li> 
</ul> 

Albo, zamiast robić to w każdym obsługi błędów, można napisać raz i ma ona zastosowanie do każdego żądania HTTP przy użyciu przechwytywania. Nigdy nie napisałem go samemu, więc pokażę ci tylko doc (przewiń w dół do sekcji Interceptory).

+0

Dodałem moje żądanie $ http, ale nie jestem pewien, jak to zrobić. @ Brocco's fiddle jest świetne, z wyjątkiem nie jestem pewien, jak to zaimplementować. Jakąkolwiek pomoc dotyczącą kodu, który dodałem? –

+0

Wygląda na to, że aktualizacja @ Brocco powinna ci pomóc. Nie mam nic do dodania, o czym nie powiedział. Powodzenia! :-) – Andrew

Powiązane problemy