2012-12-19 21 views
7

Sto tentando di eseguire la convalida lato client sui miei oggetti che ritorna attraverso WebApi. Invio l'entità tramite webapi alla schermata di modifica Entità. Io uso knockout per legare l'oggetto ai campi.Convalida lato client con WebApi

Ho già un filtro azione che gestisce tutte le convalide lato server. Come posso incorporare la convalida del lato client senza dover duplicare le annotazioni dei dati del modello di dominio?

risposta

0

Quando creo la mia API HTTP, inserisco gli oggetti modello (DTO, modelli di richiesta, ecc.) In un assembly separato che posso distribuire per client .NET.

Si consideri la seguente classe:

public abstract class UserUpdateRequestModel { 

    [Required] 
    [StringLength(50)] 
    public string Name { get; set; } 

    [Required] 
    [EmailAddress] 
    [StringLength(320)] 
    public string Email { get; set; } 
} 

Questo è quello che uso nel mio API:

public UserDto PutUser(Guid key, UserUpdateRequestModel requestModel) { 

    // Do something here 
} 

È possibile utilizzare questo stesso modello nell'applicazione client ASP.NET MVC per esempio per generare gli input HTML con gli attributi di convalida data- come ASP.NET MVC ha un modo per generare quelli basati sugli attributi di convalida dell'annotazione dei dati.

+0

Quindi si dovrebbe aggiungere una sorta di oggetto metadati (che conterrebbe gli attributi di convalida) alla risposta webapi? Come andresti a creare il codice lato client? –

+0

@kpore se hai intenzione di utilizzare ASP.NET MVC, ha un modo di crearli. Ad esempio con il metodo helper 'TextBoxFor' html. Date un'occhiata: http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-validation-to-the-model – tugberk

+0

Grazie per la risposta. In realtà non sto usando MVC. Sto usando WebApi per tutte le mie comunicazioni e persistenza. Gli helper HTML sono solo per quando si utilizzano i controller MVC classici. –

1

Con WebApi, è necessario un piccolo codice "colla" per collegare gli errori provenienti dai fallimenti di convalida del modello al validatore lato client.

function extractErrors(jqXhr, validator) { 
    var data = JSON.parse(jqXhr.responseText), // parse the response into a JavaScript object 
     errors = {}; 

    $.each(data.ModelState, function (key, value) { 
     var pieces = key.split('.'); 
     key = pieces[pieces.length - 1]; 
     errors[key] = value 
    }); 

    validator.showErrors(errors); // show the errors using the validator object 
} 

Sul modello, annotare come al solito:

[Required] 
[Display(Name = "Group Name")] 
public string Name { get; set; } 

Nella vista, aggiungere i tag ValidationMessageFor:

@Html.EditorFor(m => m.Name) 
@Html.ValidationMessageFor(m => m.Name) 
+0

Grazie per la risposta Phillip. Ciò richiede ancora un round trip del server prima che venga mostrata all'utente la convalida. Prendi l'attributo [Required], non lo vedrai aggiunto alla variabile error finché non fallisce sul server. A meno che non abbia frainteso la tua soluzione, o che abbia fallito epicamente nello spiegare il mio problema. –

+2

È vero, invia i valori al server e recupera una stringa di json. Nel mio caso, le mie forme non erano enormi, quindi ho ottenuto prestazioni simili al "lato client" e comportamento "mi piace" del lato client, nessun back post evidente. Su un piccolo modulo con 10 valdate, il costo del viaggio del server: 1/100 di un server di dev che colpisce localmente. 1/10 di secondo che colpisce un server cloud AWS dalla LAN aziendale. Questo era per un'applicazione di tipo LOB aziendale, probabilmente non appropriato per le connessioni mobili/lente. Nel mio caso, il controllo della validazione annotando il modello è valso il viaggio e ha reso lo sviluppo più pulito e più veloce. –

+0

Grazie per le informazioni extra, è in realtà abbastanza utile. Sfortunatamente alcune delle nostre forme possono essere piuttosto complesse (ad esempio, i campi di 50-100 campi nel peggiore dei casi, poiché stiamo sviluppando un sistema di finanza transazionale), probabilmente non il miglior design, ma il nostro business sta dettando questo. Stiamo ottenendo circa 300-400ms rount trip in Azure. –

Problemi correlati