2013-05-16 4 views
12

Il soggetto è autoesplicativo. Ho sviluppatori e ambienti di produzione. Sviluppatore env. è la mia macchina localhost. Dispongo di metodi di azione nei controller che impostano il codice di stato della risposta su 500 quando qualcosa non va (errore o inconsistenza logica) e restituisce Json-answer. Il mio metodo comune che si presenta come:Risposte IIS con HTML invece di JSON su ASP .NET MVC3

[HttpPost] 
public ActionResult DoSomething(int id) 
{ 
    try 
    { 
     // some useful code 
    } 
    catch(Exception ex) 
    { 
     Response.StatusCode = 500; 
     Json(new { message = "error" }, JsonBehaviour.AllowGet) 
    } 
} 

Sul lato client nella ENV produzione. quando si è verificato un errore di questo tipo, ajax.response sembra un codice HTML, invece del previsto JSON.

Considerate questo:

<div class="content-container"> 
<fieldset> 
    <h2>500 - Internal server error.</h2> 
    <h3>There is a problem with the resource you are looking for, and it cannot be displayed.</h3> 
</fieldset> 
</div> 

contesto del filtro non è un'opzione. Penso che sia una sorta di problema IIS o web.config.

SOLUZIONE: abbiamo deciso di aggiungere TrySkipIisCustomErrors in BeginRequest in Global.asax ed è risolto problemi in ogni metodo nella nostra applicazione.

+1

Avete 'return' prima della chiamata di funzione' Json'? – Zoka

+0

@Zoka, sì di corse ** ritorno ** ancora lì. Grazie. – kokosda

risposta

12

Immagino che IIS stia servendo una pagina di errore amichevole. Si potrebbe provare a saltare questa pagina impostando la proprietà TrySkipIisCustomErrors sulla risposta:

catch(Exception ex) 
{ 
    Response.StatusCode = 500; 
    Response.TrySkipIisCustomErrors = true; 
    return Json(new { message = "error" }, JsonBehaviour.AllowGet) 
} 
+0

@Khanh A, provare a saltare gli errori di iis sembra essere una sorta di hack. – kokosda

+1

No, non è affatto. La pagina di errore amichevole è una funzionalità integrata in ASP.NET Se non ti piace, non usarli, ma se hai deciso di usarli dovresti essere consapevole delle conseguenze (non puoi impostare i codici di errore con risposte personalizzate) senza dire esplicitamente a IIS. –

+0

Penso che sia una buona soluzione, ma sembra ancora essere un problema IIS. Abbiamo deciso di aggiungere 'TrySkipIisCustomErrors' in BeginRequest in Global.asax e abbiamo risolto i problemi in ogni metodo nel nostro applicazione. Grazie – kokosda

0

IIS è configurato per il trattamento di come mime-type valido? È possibile verificare ciò nelle proprietà per il server in Gestione IIS e fare clic su Tipi MIME. Se json non è presente, fai clic su "Nuovo", inserisci "JSON" per l'estensione e "application/json" per il tipo MIME.

+0

no :(Questo tipo in realtà non è stato registrato nella mia versione. L'ho aggiunto ma non è cambiato. – kokosda

0

ho risolto questo scrivendo un risultato JSON personalizzato, che utilizza json.net come il serializzatore. Questo è eccessivo per la sola correzione di IIS, ma significa che è riutilizzabile.

public class JsonNetResult : JsonResult 
{ 
    //public Encoding ContentEncoding { get; set; } 
    //public string ContentType { get; set; } 
    public object Response { get; set; } 
    public HttpStatusCode HttpStatusCode { get; set; } 

    public JsonSerializerSettings SerializerSettings { get; set; } 
    public Formatting Formatting { get; set; } 

    public JsonNetResult(HttpStatusCode httpStatusCode = HttpStatusCode.OK) 
    { 
     Formatting = Formatting.Indented; 
     SerializerSettings = new JsonSerializerSettings { }; 
     SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; 
     HttpStatusCode = httpStatusCode; 
    } 

    public override void ExecuteResult(ControllerContext context) 
    { 
     if (context == null) 
      throw new ArgumentNullException("context"); 

     HttpResponseBase response = context.HttpContext.Response; 

     response.TrySkipIisCustomErrors = true; 

     response.ContentType = !string.IsNullOrEmpty(ContentType) ? ContentType : "application/json"; 

     if (ContentEncoding != null) 
      response.ContentEncoding = ContentEncoding; 

     response.StatusCode = (int) HttpStatusCode; 

     if (Response != null) 
     { 
      JsonTextWriter writer = new JsonTextWriter(response.Output) { Formatting = Formatting }; 

      JsonSerializer serializer = JsonSerializer.Create(SerializerSettings); 
      serializer.Serialize(writer, Response); 

      writer.Flush(); 
     } 
    } 
} 

Usa:

  try 
      { 
       return new JsonNetResult() 
       { 
        Response = "response data here" 
       }; 
      } 
      catch (Exception ex) 
      { 
       return new JsonNetResult(HttpStatusCode.InternalServerError) 
       { 
        Response = new JsonResponseModel 
        { 
         Messages = new List<string> { ex.Message }, 
         Success = false, 
        } 
       }; 
      }