2013-05-16 9 views
12

Das Thema ist selbsterklärend. Ich habe Entwickler- und Produktionsumgebungen. Entwickler env. ist meine localhost Maschine. Ich habe Aktionsmethoden in Contoler, die Antwort-Status-Code auf 500 setzt, wenn etwas schief gelaufen ist (Fehler aufgetreten, oder logische Inkonsistenz) und gibt JSON-Antwort zurück. Meine übliche Methode sieht so aus:IIS-Antworten mit HTML anstelle von JSON auf 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) 
    } 
} 

Auf der Client-Seite in der Produktion env. Wenn ein solcher Fehler aufgetreten ist, sieht ajax.response wie ein HTML-Code statt der erwarteten JSON aus.

Bedenken Sie:

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

Filter Kontext ist keine Option. Ich denke, es ist eine Art von IIS oder web.config Problem.

LÖSUNG: Wir entschieden TrySkipIisCustomErrors in Beginrequest in Global.asax hinzufügen und es wird Probleme in jeder Methode in unserer Anwendung gelöst.

+1

Sie haben Sie 'return' vor dem' Json' Funktionsaufruf? – Zoka

+0

@ Zoka, ja der corse ** Rückkehr ** immer noch da. Vielen Dank. – kokosda

Antwort

12

Ich denke, dass IIS einige freundliche Fehlerseite bietet. Sie könnten versuchen, diese Seite übersprungen, indem die TrySkipIisCustomErrors Eigenschaft auf die Antwort Einstellung:

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

@Khanh To, versucht zu überspringen iis Fehler scheint eine Art von Hack sein. – kokosda

+1

Nein, überhaupt nicht. Es ist nicht ein Die freundliche Fehlerseite ist eine in ASP.NET integrierte Funktion.Wenn Sie sie nicht mögen, verwenden Sie sie nicht.Wenn Sie sich jedoch entschieden haben, sie zu verwenden, sollten Sie sich der Konsequenzen bewusst sein (Sie können keine Fehlerstatuscodes festlegen mit benutzerdefinierten Antworten), ohne IIS explizit zu sagen, dass. –

+0

Ich denke, es ist eine gute Lösung, aber immer noch scheint ein IIS - Problem zu sein.Wir haben beschlossen, 'TrySkipIisCustomErrors' in BeginRequest in Global.asax und es ist gelöst Probleme in jeder Methode in unserem Vielen Dank. – kokosda

0

Ist Ihr IIS für die Behandlung von application/json als gültigen konfiguriert? Sie können dies in den Eigenschaften für den Server im IIS-Manager überprüfen und auf MIME-Typen klicken. Wenn json nicht vorhanden ist, klicken Sie auf "Neu", geben Sie "JSON" für die Erweiterung und "application/json" für den MIME-Typ ein.

+0

nope :(Dieser Typ wurde eigentlich nicht auf meiner iis registriert. Ich habe ihn hinzugefügt, aber nichts geändert. – kokosda

0

Ich löste dies durch einen benutzerdefinierten json Ergebnis schreiben, die als Serializer verwendet json.net. Dies ist Overkill nur für den IIS-Fix, aber es bedeutet, dass es wiederverwendbar ist.

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(); 
     } 
    } 
} 

Verwendung:

  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, 
        } 
       }; 
      } 
Verwandte Themen