web-dev-qa-db-fra.com

Comment activer les demandes d’origine croisée dans ASP.NET MVC 4 sur POST en utilisant Angular 2

J'ai du mal à faire une demande POST avec CORS.

J'ai en fait une classe qui ajoute un en-tête de réponse correct sur mes méthodes dans mon contrôleur

using System;
using System.Web.Mvc;

public class AllowCrossSiteAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost:4200");
        filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Headers", "*");
        filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Credentials", "true");

        base.OnActionExecuting(filterContext);
    }
}

et je l'utilise comme ça

[AllowCrossSite]
public ActionResult GetReportParameters(string IdRapport)

et je reçois le résultat attendu  enter image description here

Mais le problème, c’est lorsque j’essaie de faire une demande POST avec un en-tête personnalisé pour transmettre ce type de contenu spécifique

'Content-Type': 'application/json; charset=utf-8'

Je reçois en fait ces en-têtes de réponse

 enter image description here

Donc, c'est comme si rien n'était fait à propos de l'en-tête même si je vais correctement dans ma classe d'attribut.

Voici mon recto dans Angular 2 service

const headers = new Headers({ 'Content-Type': 'application/json; charset=utf-8' });
const options = new RequestOptions({ headers: headers , withCredentials: true });

const mock = {
  name: 'TitreRegroupement1',
  visible: false,
  type: 'System.String',
  value: 'Test'
};

// tslint:disable-next-line:max-line-length
const body = JSON.stringify({ idRapport: '00392024-d171-4f39-9c5c-97a51f53fd54', filtre: '', exportFormat: '', parameters: data });

return this.http.post('http://localhost:8080/ReportingViewer/ExportReport', body, options)
  .map((response: Response) => {
      return this.extractSingleData(response, Parameters);
  })
  .catch(this.handleError);
}

En utilisant postman, il n'y a pas de problème à déclarer, tout se déroule correctement. Je peux accéder à mes paramètres à partir de la méthode à l'intérieur du contrôleur sans problème.

Si un corps peut me donner des conseils pour comprendre, je suis heureux de les entendre! :)

7
Fitch

Merci à vous deux, j'ai enfin trouvé comment le faire fonctionner.

J'applique d'abord ce qui m'a été proposé sideshowbarker

if (Request.Headers.AllKeys.Contains("Origin", StringComparer.OridinalIgnoreCase) &&
    Request.HttpMethod == "OPTIONS") {
    Response.Flush();
}

et il me manquait quelque chose dans mes en-têtes, je faisais "*" tout le chemin mais finalement avec ces paramètres cela a fonctionné

filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");

pour ceux qui sont intéressés par la forme finale de ma classe ici, il est

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

namespace Via.Client.WebMvc
{
    public class AllowCrossSiteAttribute : System.Web.Mvc.ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            HttpContext ctx = System.Web.HttpContext.Current;

            filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost:4200");
            filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
            filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Credentials", "true");

            if (filterContext.HttpContext.Request.HttpMethod == "OPTIONS")
            {
                filterContext.HttpContext.Response.Flush();
            }

            base.OnActionExecuting(filterContext);
        }
    }
}
4
Fitch

Votre code JavaScript frontal force votre navigateur à lancer une demande de contrôle en amont OPTIONSde CORS.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests

Vous devez modifier le code côté serveur pour traiter cette demande OPTIONSen ajoutant, par exemple:

if (Request.Headers.AllKeys.Contains("Origin", StringComparer.OridinalIgnoreCase) &&
    Request.HttpMethod == "OPTIONS") {
    Response.Flush();
}

Ou consultez https://stackoverflow.com/search?q=%5Basp.net-mvc%5D+%5Bcors%5D+options pour de nombreuses autres réponses connexes.

3
sideshowbarker

Le code que vous avez essayé est tout bon. Cela devrait être un travail, mais dans votre cas, cela ne fonctionne pas.

J'ai une référence pour vous à ce sujet, vous devez vérifier

Définition de l'accès-contrôle-autorisation-origine dans ASP.Net MVC - méthode la plus simple possible

1
Manoj