Domanda

C'è un sacco di post molto buona e le spiegazioni su come implementare la convalida con ASP.NET MVC, e preferisco uno di questi:

Comunque, mi piace molto chiamare ActionMethods tramite metodo jquery $ .ajax. Uno dei motivi per cui voglio usare $ .ajax è perché ci saranno un sacco di punti di vista parziali caricati nella pagina in modo dinamico (anche sotto forma di creazione di entità) tramite $ .ajax chiamate e non posso restituire la vista - perderò tutti i contenuti caricati in modo dinamico.

Per darvi una visione migliore del problema, vi posterò qualche codice semplice da spiegare come mi piacerebbe chiamare azioni controllori e gestire le risposte a cliente, codice jQuery.

Il controller ActionMethod:

    public ActionResult CreateCustomer(string name, string accountNumber)
    {
        try
        {
            CustomerService.InsertCustomer(name, accountNumber);

            return Json(new ActionInfo()
            {
                Success = true,
                Message = "Customer Is Successfully Created"
            });

        }
        catch (Exception ex)
        {
            return Json(new ActionInfo()
            {
                Success = false,
                Message = ex.Message
            });
        }
    }

Calling e manipolazione in codice client:

$.ajax({
type: "POST",
url: $form.attr('action'),// /MyController/CreateCustomer
data: $form.serialize(),
error: HandleUnespectedError,
dataType: "json",
success: function(response) {

    if (response.Success)
        alert("Success: " + response.Message);
    else
        alert("Error: " + response.Message);
}});

C'è un buon modo per fare alcuni di questi quadri di validazione per lavorare nel modo che ho bisogno? So che posso aggiungere errori di convalida in ActionInfo, e poi gestirlo nel client, ma che avrebbe essere già un edificio del mio una convalida, credo.

È stato utile?

Soluzione

Ho avuto un grande successo facendo la convalida tramite la tecnologia AJAX utilizzando attributi annotazioni di dati. Al fine di verificare la validità dei dati, si desidera utilizzare la proprietà ModelState del controller, che ha una proprietà di un proprio chiamato IsValid. Vi consiglio vivamente di dare uno sguardo alla convalida delle annotazioni di dati attributi esercitazione dal sito ufficiale ASP.NET MVC.

Prima di tutto, si vuole modificare la vostra azione di controllo per accettare il vostro modello a oggetti come parametro, piuttosto che un nome e numero di conto separato. Questo renderà l'esecuzione della convalida, che dimostrerò qui di seguito, molto più semplice. Dal tuo esempio, la mia ipotesi migliore è che l'oggetto del modello è, o sarebbe, chiamato Cliente. Si potrebbe avere il seguente codice per definire l'oggetto del modello e la vostra azione di controllo ...

// model object
public class Customer
{
  public Int32 Id {get; set;}
  public String Name {get; set;}
  public String AccountNumber {get; set;}
}

// controller
public class CustomerController : Controller
{
  public ActionResult CreateCustomer( [Bind(Exclude = "Id")] Customer customer )
  {
     // controller action code
  }
}

Assicurarsi che i campi del modulo sono chiamati a corrispondere ai nomi delle proprietà dell'oggetto cliente in modo ASP.NET MVC può automagicamente legarli. L'attributo "Bind", in questo caso, sta dicendo ASP.NET MVC di ignorare il "Id" proprietà della classe Customer durante l'associazione campi del modulo per modellare proprietà. Poiché si tratta di un nuovo cliente, non abbiamo un Id ancora, quindi possiamo tranquillamente lasciare l'ID come qualunque sia il valore di default è e lasciare lo strato di dati per capire il modo migliore per generare esso.

Una volta che il controllore ha costruito l'oggetto del modello per il metodo d'azione, la sua validità può essere facilmente controllato tramite la proprietà ModelState.IsValid. Come ci si potrebbe aspettare, ritorna vero se le proprietà modello sono validi, oppure false se 1 o più proprietà non sono validi.

Dalla domanda iniziale, sembra che il metodo CustomerService.InsertCustomer sta gettando le eccezioni quando la validazione fallisce. Questo è completamente inutile. InsertCustomer dovrebbe solo bisogno di eseguire qualsiasi operazioni di dati sono necessari per l'inserimento del nuovo record. A meno che non si desidera astratte eccezioni specifiche di implementazione, come SqlException, InsertCustomer non dovrebbe davvero bisogno di prendere o gettare le eventuali eccezioni, ma può molto probabilmente solo lasciare qualsiasi eccezioni bolla fino al controller (o chi il chiamante può essere).

Il risultato finale di tutto questo, potrebbe essere un'azione di controllo che appare come il seguente:

public ActionResult CreateCustomer( [Bind(Exclude = "Id")] Customer customer )
{
  // model is invalid
  if (!ModelState.IsValid)
  {
    return Json(new ActionInfo()
    {
      Success = false,
      Message = "Validation failed" // you will probably want a more robust message :-)
    });
  }

  // service method accepts a Customer object rather than arbitrary strings  
  CustomerService.InsertCustomer(customer);

  return Json(new ActionInfo()
  {
    Success = true,
    Message = "Customer created successfully."
  });

}

Se si desidera segnalare errori inaspettati, come eccezioni relative del database, allora si può certamente aggiungere un blocco try / catch intorno la chiamata a InsertCustomer, e restituire il risultato necessario per la visualizzazione del messaggio di errore al client.

Altri suggerimenti

Questo è più di un anno dopo aver chiesto alla tua domanda, ma ho coperto la validazione lato server con l'Ajax chiamate nel mio post sul blog che potrebbe essere di molto interesse per voi. Vedo che ritorni risultati difettosi, come chiamate HTTP di successo. Ho gestito in modo diverso (Credo che sia più corretto dal $.ajax ha la capacità di funzionalità success e risposta error). E il tuo esempio particolare è un perfetto esempio che potrebbero essere attuate con la funzionalità spiego nel mio post sul blog.

In sostanza, invece di restituire sempre una risposta positiva (ma con le proprietà impostate per dire al cliente che l'elaborazione lato server non) ho piuttosto butto un exeception sul server e gestire di conseguenza sul client. Sto utilizzando una classe ModelStateException personalizzato insieme a un filtro azione HandleModelStateException.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top