7 Stimmen

ASP.NET MVC 3 JSONP: Funktioniert dies mit JsonValueProviderFactory?

Phil Haack hat eine ausgezeichnete Blog-Beitrag über die Verwendung von JSON, Datenbindung und Datenvalidierung.

Geben Sie die Sicherheitsbeschränkung "gleiche Herkunft" des Browsers und JSONP ein, wobei Sie $.getJSON() verwenden, um den Inhalt abzurufen.

Gibt es eine eingebaute MVC 3 Möglichkeit, dies zu tun, oder muss ich den Rat von folgen Stellen wie diese ? Können Sie Inhalte veröffentlichen? Ich frage, weil mein Kollege unter anderem ein JsonPfilterAttribute implementiert hat, damit das funktioniert. Es ist natürlich bevorzugt, dass zu vermeiden, wenn etwas bereits in MVC 3 existiert.

Edit :

Zusammenfassung: Alles funktioniert mit Ausnahme des Zugriffs auf eine POST Variable, d.h. wie kann ich auf die POST Variable im Kontext? (Kommentar im letzten Abschnitt des Codes)

Ich habe mich entschieden, dieses Format für den Aufruf des Servers zu verwenden:

$.ajax({
    type: "GET",
    url: "GetMyDataJSONP",
    data: {},
    contentType: "application/json; charset=utf-8",
    dataType: "jsonp",
    jsonpCallback: "randomFunctionName"
});

Das führt zu dieser Antwort:

randomFunctionName([{"firstField":"111","secondField":"222"}]);

Und all dies funktioniert sehr gut, wenn ich eine GET . Allerdings kann ich dies immer noch nicht als POST . Hier ist der Originalcode von Nathan Bridgewater ici . In dieser Zeile werden die POST-Daten nicht gefunden:

context.HttpContext.Request["callback"];

Entweder sollte ich Zugang zu Form oder die MVC-Datenvalidatoren entfernen die POST-Variablen auf irgendeine Weise.

Wie sollte context.HttpContext.Request["callback"]; geschrieben werden, um auf die POST Variable oder werden diese Werte von MVC aus irgendeinem Grund entfernt?

namespace System.Web.Mvc
{   public class JsonpResult : ActionResult
    {   public JsonpResult() {}

        public Encoding ContentEncoding { get; set; }
        public string ContentType { get; set; }
        public object Data { get; set; }
        public string JsonCallback { get; set; }

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

            this.JsonCallback = context.HttpContext.Request["jsoncallback"];

            // This is the line I need to alter to find the form variable:

            if (string.IsNullOrEmpty(this.JsonCallback))
                this.JsonCallback = context.HttpContext.Request["callback"];

            if (string.IsNullOrEmpty(this.JsonCallback))
                throw new ArgumentNullException(
                    "JsonCallback required for JSONP response.");

            HttpResponseBase response = context.HttpContext.Response;

            if (!String.IsNullOrEmpty(ContentType))
               response.ContentType = ContentType;
            else
               response.ContentType = "application/json; charset=utf-8";

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

            if (Data != null)
            {   JavaScriptSerializer serializer = new JavaScriptSerializer();
                response.Write(string.Format("{0}({1});", this.JsonCallback,
                    serializer.Serialize(Data)));
    }   }   }

    //extension methods for the controller to allow jsonp.
    public static class ContollerExtensions
    {
        public static JsonpResult Jsonp(this Controller controller, 
               object data)
        {
            JsonpResult result = new JsonpResult();
            result.Data = data;
            result.ExecuteResult(controller.ControllerContext);
            return result;
        }
    }
}

39voto

Darin Dimitrov Punkte 990883

Was den Empfang eines JSON-Strings und dessen Bindung an ein Modell betrifft, so ist die JsonValueProviderFactory erledigt diese Aufgabe in ASP.NET MVC 3 von Haus aus. Aber es gibt nichts eingebautes für die Ausgabe von JSONP. Sie könnten eine benutzerdefinierte JsonpResult :

public class JsonpResult : JsonResult
{
    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        var request = context.HttpContext.Request;
        var response = context.HttpContext.Response;
        string jsoncallback = (context.RouteData.Values["jsoncallback"] as string) ?? request["jsoncallback"];
        if (!string.IsNullOrEmpty(jsoncallback))
        {
            if (string.IsNullOrEmpty(base.ContentType))
            {
                base.ContentType = "application/x-javascript";
            }
            response.Write(string.Format("{0}(", jsoncallback));
        }
        base.ExecuteResult(context);
        if (!string.IsNullOrEmpty(jsoncallback))
        {
            response.Write(")");
        }
    }
}

Und dann in Ihrer Controller-Aktion:

public ActionResult Foo()
{
    return new JsonpResult
    {
        Data = new { Prop1 = "value1", Prop2 = "value2" },
        JsonRequestBehavior = JsonRequestBehavior.AllowGet
    };
}

die von einer anderen Domäne aus konsumiert werden könnten mit $.getJSON() :

$.getJSON('http://example.com/home/foo?jsoncallback=?', function(data) {
    alert(data.Prop1);
});

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X