2014-04-15 10 views
13

Sto costruendo un'applicazione AngularJS SPA con WebApi per il backend. Sto usando gli attributi per la validazione del modello sul server, se la validazione fallisce questo è ciò che ritorna da ModelState.Come eseguire il rendering degli errori sul client? AngularJS/WebApi ModelState

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

Come si esegue il rendering al client con 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

cosa hai provato? Puoi gestirlo con dozzine di metodi. Questa domanda è molto ampia. Per prima cosa devi scegliere il comportamento della tua app per inviarli (avviso? Popup? Notifica adesiva?) ... –

+0

Scusa, non intendevo per il modo di rendering. Non ero sicuro di come ottenere gli errori dall'array ModelState che è stato restituito con l'errore 400 BadRequest –

risposta

15

Quando si effettua la chiamata al server, catturare l'errore in base al rifiuto della $http promessa.

Poi nel controller Vorrei suggerire appiattendo la risposta ad una serie di errori su gestione dell'errore per la visualizzazione come mostrato in questo fiddle example:

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

a mettere tutto insieme:

// 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

Ho aggiunto la richiesta $ http nel mio codice, ma come ottengo quegli errori dal BadRequest che viene restituito e inserire la variabile 'resp'. Sono ancora nelle prime fasi dell'apprendimento di JS, solo 2 mesi in questo ed è la mia prima esposizione a JS e AngularJS. E 'questo a che serve il .push? –

+0

Ho aggiornato il codice nella mia risposta per mostrare una soluzione più completa. – Brocco

+0

Buono per andare e ora capisco il processo. Grandi cose. –

3

Il modo più semplice potrebbe essere quello di afferrare tutti gli errori da ModelState e inserirli in una nuova proprietà su $ 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; 
}; 

Allora nel tuo codice HTML ...

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

O, invece di fare questo in tutte error handler, si potrebbe scrivere una volta e farla applicare ad ogni richiesta HTTP utilizzando un intercettore. Non ne ho mai scritto uno anch'io, quindi ti indicherò semplicemente lo doc (scorri verso il basso fino alla sezione Interceptors).

+0

Ho aggiunto la mia richiesta $ http ma non sono sicuro di come completare questo. @ Il violino di Brocco è fantastico, tranne che non sono sicuro di come implementarlo. Qualche aiuto con il codice che ho aggiunto? –

+0

Sembra che l'aggiornamento di @ Brocco dovrebbe aiutarti. Non ho nulla da aggiungere che non abbia detto. In bocca al lupo! :-) – Andrew

Problemi correlati