2014-04-24 11 views
5

In ASP.NET MVC mi piace molto la funzionalità che tenta automaticamente di riempire i parametri di un'azione dai valori della richiesta.Modo pulito per evitare l'errore "voce nullo per ID parametro di tipo non annullabile" per i parametri di input

Rende un sacco di cose molto pulite e il mio modello gerarchico per le forme può viaggiare con facilità attraverso il cavo.

C'è comunque un fastidioso problema. L'eccezione automatica per i parametri mancanti non annullabili. Non è che la struttura sia sbagliata. Capisco il ragionamento alla base di questo, ma:

  1. Ci sono alcuni casi in cui ho una sola int param come input, in cui è richiesto uno specifico oggetto (una pagina dei dettagli di un prodotto, per esempio).
  2. Il parametro è un parametro GET, quindi è visibile nell'URL ed è facile da modificare.
  3. Se l'utente cambia il parametro nell'url il server web risponde con una pagina di errore, registra l'errore, ecc

Questo tipo di errore dovrebbe essere gestito bene all'interno dell'applicazione, non ho bisogno di inquinare i miei registri con l'errore, anche un errore 404 per questi casi sarebbe più appropriato IMHO, poiché senza il parametro identificativo "la risorsa non può essere trovata".

Ho alcune idee su come evitare questo, ma voglio qualcosa di trasparente che gestisca questo in un unico posto.

La cosa che ho fatto finora è rendere il parametro int?.

Non proprio trasparente, ho bisogno di controllare ID.HasValue ovunque e di lanciare un 404 esplicitamente. Questo inquina la logica di azione.

Qual è il posto migliore per affrontare questo?

EDIT:

Vorrei anche sottolineare che, anche se gettando un HttpException(404,"") è ancora un'eccezione, ma dal momento che i browser alla ricerca di favicon, ecc e crawler fare un sacco di richieste al cattivi gli URL in ogni caso, tutta la mia registrazione , avvisi, ecc. è configurato di conseguenza.

+0

Sono d'accordo sul fatto che un 404 sarebbe più appropriato. Sarebbe bello se potessi configurare la tua app web per rispondere a percorsi non validi con 404 in produzione. – Sean

risposta

1

Penso che il gancio appropriato qui sia il ModelBinder.

Dovrai elaborare una strategia per quando desideri restituire un 404. Sulla base dei tuoi dettagli sopra, e per semplicità, assumerò che ogni volta che un parametro denominato "id" è nullo o non è passato quando previsto, che questo genera un 404. Ecco l'esempio del codice ModelBinder.

using System.Net; 
using System.Web; 
using System.Web.Mvc; 

public class MyModelBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var result = base.BindModel(controllerContext, bindingContext); 

     if (result == null && bindingContext.ModelName.ToLower() == "id") 
     { 
      throw new HttpException((int)HttpStatusCode.NotFound, null); 
     } 

     return result; 
    } 
} 

È filo questo in Global.asax:

protected void Application_Start() 
{ 
    ModelBinders.Binders.DefaultBinder = new MyModelBinder(); 
} 

Per ottenere più granulare, si potrebbe aggiungere un attributo solo per parametri che si desidera questo comportamento per, e l'uso di riflessione per ispezionare per l'attributo e solo lanciare l'eccezione 404 in questo caso, ci sarà una penalità di prestazioni per quello. Pertanto è possibile collegare specifici ModelBinder solo per i modelli che presentano questo comportamento in base alle esigenze. Oppure si potrebbe mantenere un dizionario di Controller/Azioni/Parametri per applicare anche il comportamento.

Modifica: si nota inoltre che si sono specificamente interessati alle richieste GET. Questo valore è disponibile nel raccoglitore modello: controllerContext.RequestContext.HttpContext.Request.HttpMethod.

+0

Grazie per questa risposta. Vado a dare un'occhiata a "ModelBinder" e accetto la tua risposta se funziona davvero e si adatta alle mie esigenze (molto probabilmente lo sarà). – SoonDead

Problemi correlati