2008-11-19 9 views
0

J'ai un service WCF décoré avec des attributs WebInvoke et une liaison WebHttp pour l'activation JSON. Le service peut être accédé à partir de JavaScript jusqu'à ce que nous essayons de le faire fonctionner à travers le domaine. Pouvez-vous s'il vous plaît recommander comment faire fonctionner ce domaine?Cross Domain JSON Enabled WCF

Nous avons essayé de créer un gestionnaire de proxy web mais il demande "Bad Request" à chaque fois que WebHttpRequest essaie d'y accéder.

Répondre

0

Ce que je devais faire était de créer un proxy. La demande de domaine croisé ne fonctionne qu'avec le verbe GET et pas avec POST. Toute ma demande passe par le proxy, et si c'est un POST, alors il agit comme un proxy typique. Si la requête utilise un GET, je dois le convertir en POST. (Je spécifie POST comme le verbe dans mes contrats de service).

Du côté client, j'utilise la fonctionnalité josnp (json avec remplissage) de JQuery pour ajouter les informations correctes à la chaîne de requête.

private static readonly Properties.Settings settings = new Properties.Settings(); 

    public void ProcessRequest(HttpContext context) 
    { 
     try 
     { 
      string wcfAddress = context.Request.QueryString["WcfAddress"];      

      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(settings.WCFAddress + wcfAddress); 

      request.ContentType = "application/json"; 

      request.Method = "POST"; 

      if (context.Request.RequestType == "GET") 
      { 
       string callback = context.Request.QueryString["callback"]; 
       string qs = context.Request.QueryString[null]; 
       byte[] body = body = Encoding.UTF8.GetBytes(qs); 

       request.ContentLength = body.Length; 

       request.GetRequestStream().Write(body, 0, body.Length); 

       HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 

       using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8)) 
       { 

        string contents = reader.ReadToEnd(); 

        contents = callback + "(" + contents + ");"; 

        context.Response.ContentType = "application/json"; 

        context.Response.Write(contents); 

        response.Close(); 

        reader.Close(); 
       } 
      } 
      else if (context.Request.RequestType == "POST") 
      { 
       byte[] body = new byte[context.Request.ContentLength]; 

       context.Request.InputStream.Read(body, 0, body.Length); 

       request.ContentLength = body.Length; 

       request.GetRequestStream().Write(body, 0, body.Length); 

       HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 

       using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8)) 
       { 
        string contents = reader.ReadToEnd(); 

        context.Response.ContentType = "application/json"; 

        context.Response.Write(contents); 

        response.Close(); 

        reader.Close(); 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      System.Diagnostics.Trace.WriteLine(ex.ToString()); 
     } 
    } 
0

Suivez les étapes indiquées dans Partie 1-4 de this excellent article series et vous vous retrouvez avec une solution propre. Je l'utilise en production sans aucun problème.

Vous devez effectuer un ajustement pour le faire fonctionner avec tous les navigateurs. Dans CorsDispatchMessageInspector.BeforeSendReply commentaire sur le chèque:

if (! State.Message = null)

sinon les en-têtes "Allow" ne sont appliquées aux demandes de pré-vol, mais pas à la demande réelle.

0

Pour résoudre le problème procédez comme suit

Créer une Global.asax et ajouter du code ci-dessous pour activer cross-domain Ajax POST

public void Application_BeginRequest(object sender, EventArgs e) 
     { 
      HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); 
      HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST,OPTIONS"); 

      if ((HttpContext.Current.Request.HttpMethod == "OPTIONS")) 
      { 

       HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept"); 
       HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000"); 
       HttpContext.Current.Response.End(); 
      } 
     } 
    }