it-swarm.com.de

MVC-Web-API: Auf der angeforderten Ressource ist kein Header "Access-Control-Allow-Origin" vorhanden

Ich habe alles versucht, was in diesem Artikel geschrieben ist: http://www.asp.net/web-api/overview/security/enabling-cross-Origin-requests-in-web-api , aber nichts funktioniert. Ich versuche, Daten von webAPI2 (MVC5) für die Verwendung in einer anderen Domäne mithilfe von angleJS zu erhalten.

mein Controller sieht so aus:

namespace tapuzWebAPI.Controllers
{
    [EnableCors(origins: "http://local.tapuz.co.il", headers: "*", methods: "*", SupportsCredentials = true)]
    [RoutePrefix("api/homepage")]
    public class HomePageController : ApiController
    {
        [HttpGet]
        [Route("GetMainItems")]
        //[ResponseType(typeof(Product))]
        public List<usp_MobileSelectTopSecondaryItemsByCategoryResult> GetMainItems()
        {


            HomePageDALcs dal = new HomePageDALcs();
            //Three product added to display the data

            //HomePagePromotedItems.Value.Add(new HomePagePromotedItem.Value.FirstOrDefault((p) => p.ID == id));


            List<usp_MobileSelectTopSecondaryItemsByCategoryResult> items = dal.MobileSelectTopSecondaryItemsByCategory(3, 5);
            return items;

        }      
    }
}
99
Noa Gani

Sie müssenCORSin Ihrer Web Api aktivieren. Der einfachere und bevorzugte Weg, um CORS global zu aktivieren, besteht darin, Folgendes in web.config hinzuzufügen:

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Access-Control-Allow-Origin" value="*" />
      <add name="Access-Control-Allow-Headers" value="Content-Type" />
      <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

Bitte beachten Sie, dass die Methods alle einzeln angegeben sind, anstatt * zu verwenden. Dies liegt daran, dass bei der Verwendung von * ein Fehler auftritt.

Sie können CORS auch über den Code aktivieren.

Update
Das folgende NuGet -Paket ist erforderlich: Microsoft.AspNet.WebApi.Cors.

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.EnableCors();

        // ...
    }
}

Dann können Sie das [EnableCors]-Attribut für Aktionen oder Controller wie folgt verwenden

[EnableCors(origins: "http://www.example.com", headers: "*", methods: "*")]

Oder Sie können es global registrieren

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute("http://www.example.com", "*", "*");
        config.EnableCors(cors);

        // ...
    }
}

Sie müssen auch die Preflight OptionsAnforderungen mit HTTP OPTIONS-Anforderungen behandeln.

Web API muss auf die Options-Anforderung antworten, um zu bestätigen, dass sie tatsächlich für die Unterstützung von CORS konfiguriert ist.

Dazu müssen Sie lediglich ein leere Antwort zurückschicken. Sie können dies in Ihren Handlungen tun, oder Sie können dies global wie folgt tun:

# Global.asax.cs
protected void Application_BeginRequest()
{
    if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
    {
        Response.Flush();
    }
}

Diese zusätzliche Prüfung wurde hinzugefügt, um sicherzustellen, dass alte APIs, die nur GET- und POST-Anforderungen akzeptieren, nicht ausgenutzt werden. Stellen Sie sich vor, Sie senden eine DELETE-Anfrage an eine API, die entworfen wurde, wenn dieses Verb nicht vorhanden war. Das Ergebnis ist unvorhersehbar und die Ergebnisse könnten gefährlich sein.

@ Mihai-Andrei Dinculescus Antwort ist richtig, aber zum Vorteil der Suchenden gibt es auch einen subtilen Punkt, der diesen Fehler verursachen kann. 

Durch das Hinzufügen eines "/" am Ende Ihrer URL kann EnableCors in allen Fällen (z. B. von der Startseite) aus nicht funktionieren.

Das heißt Das wird nicht funktionieren

var cors = new EnableCorsAttribute("http://testing.azurewebsites.net/", "*", "*");
config.EnableCors(cors);

aber das wird funktionieren:

var cors = new EnableCorsAttribute("http://testing.azurewebsites.net", "*", "*");
config.EnableCors(cors);

Der Effekt ist der gleiche, wenn das EnableCors-Attribut verwendet wird.

22
HockeyJ

Ich habe alle oben genannten Schritte von Mihai-Andrei Dinculescu befolgt.
Aber in meinem Fall brauchte ich 1 mehr step, weil http OPTIONS in der Web.Config durch die folgende Zeile deaktiviert wurde.

<remove name="OPTIONSVerbHandler" />

Ich habe es gerade aus Web.Config entfernt (kommentiere es wie unten) und Cors wirkt wie ein Zauber

<handlers>
  <!-- remove name="OPTIONSVerbHandler" / -->
</handlers>
17
AlbertSY

Dies kann an der Installation von Cors-Nuget-Paketen liegen.

Wenn Sie nach dem Installieren und Aktivieren von cors von nuget auf das Problem stoßen, können Sie Web Api erneut installieren.

Führen Sie im Paket-Manager Update-Package Microsoft.AspNet.WebApi -reinstall aus.

9
Bimal Das

Probieren Sie dies aus, um sicherzustellen, dass Sie CORS richtig konfiguriert haben:

[EnableCors(origins: "*", headers: "*", methods: "*")]

Funktioniert immer noch nicht? Überprüfen Sie die Anwesenheit von HTTP-Headern.

5
Andrei

Damit ein CORS-Protokoll funktioniert, benötigen Sie eine OPTIONS-Methode für jeden Endpunkt (oder einen globalen Filter mit dieser Methode), die diese Header zurückgibt: 

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: content-type

Der Grund ist, dass der Browser zuerst eine OPTIONS-Anforderung sendet, um Ihren Server zu "testen" und die Berechtigungen anzuzeigen

4
sam

@ Mihai-Andrei Dinculescus Antwort funktionierte für mich, z.

  • Hinzufügen eines <httpProtocol> in der <system.webServer>-Sektion der web.config
  • Leere Antwort für OPTIONS-Anforderungen über die angegebene Application_BeginRequest() in global.asax zurückgeben

Nur dass seine Prüfung auf Request.Headers.AllKeys.Contains("Origin") für mich NICHT funktioniert hat, da die Anfrage ein origing enthielt, also mit Kleinbuchstaben. Ich denke, mein Browser (Chrome) sendet es so für CORS-Anfragen. 

Ich habe dieses Problem etwas allgemeiner gelöst, indem ich stattdessen Groß- und Kleinschreibung ohne Berücksichtigung von Groß- und Kleinschreibung Variante seines Contains-Checks verwende: if (culture.CompareInfo.IndexOf(string.Join(",", Request.Headers.AllKeys), "Origin", CompareOptions.IgnoreCase) >= 0) {

1
Bart

Ich weiß, dass ich sehr spät komme. Für jeden, der auf der Suche ist, dachte ich, ich würde veröffentlichen, was ENDLICH für mich funktioniert. Ich behaupte nicht, dass es die beste Lösung ist - nur, dass es funktioniert hat.

Unser WebApi-Dienst verwendet die Methode config.EnableCors (corsAttribute). Trotzdem würde es bei den Anfragen vor dem Flug immer noch scheitern. @ Mihai-Andrei Dinculescus Antwort lieferte den Hinweis für mich. Zunächst habe ich seinen Application_BeginRequest () - Code hinzugefügt, um die Optionsanforderungen zu leeren. Das hat bei mir NOCH nicht funktioniert. Das Problem ist, dass WebAPI der OPTIONS-Anforderung immer noch keinen der erwarteten Header hinzufügte. Es alleine zu spülen hat nicht funktioniert - aber es gab mir eine Idee. Ich habe die benutzerdefinierten Header, die andernfalls über die Datei web.config hinzugefügt würden, zur Antwort auf die Anforderung OPTIONS hinzugefügt. Hier ist mein Code:

protected void Application_BeginRequest()
{
  if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
  {
    Response.Headers.Add("Access-Control-Allow-Origin", "https://localhost:44343");
    Response.Headers.Add("Access-Control-Allow-Headers",
      "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
    Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
    Response.Headers.Add("Access-Control-Allow-Credentials", "true");
    Response.Flush();
  }
}

Dies gilt natürlich nur für die OPTIONS-Anforderungen. Alle anderen Verben werden von der CORS-Konfiguration behandelt. Wenn es eine bessere Herangehensweise gibt, bin ich ganz Ohr. Es fühlt sich für mich wie ein Betrüger an und ich würde es vorziehen, wenn die Überschriften automatisch hinzugefügt würden, aber das ist es, was schließlich funktioniert hat und mir erlaubt hat, weiterzumachen.

1
John Groft

Ich fange den nächsten Fall über Korsetts ein. Vielleicht ist es für jemanden nützlich. Wenn Sie Ihrem Server die Funktion 'WebDav Redirector' hinzufügen, sind die PUT- und DELETE-Anforderungen fehlgeschlagen.

Daher müssen Sie 'WebDAVModule' von Ihrem IIS -Server entfernen:

  • Msgstr "" "Schleifen Sie in der Konfiguration der IIS - Module das WebDAVModule hoch. Wenn Ihr Webserver es hat, entfernen Sie es.".

Oder fügen Sie Ihrer Konfiguration hinzu:

<system.webServer>
<modules>
  <remove name="WebDAVModule"/>
</modules>
<handlers>
  <remove name="WebDAV" />
  ...
</handlers>

0
Andrey R

Ich hatte alles versucht, was ich im Internet finden konnte, einschließlich der Methoden, die für diese Antwort angegeben wurden. Nachdem ich fast den ganzen Tag versucht habe, das Problem zu lösen, habe ich die Lösung gefunden, die für mich wie ein Zauber gewirkt hat.

kommentieren Sie in der Datei WebApiConfig im Ordner App_Start alle Codezeilen und fügen Sie den folgenden Code hinzu:

`public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        config.EnableCors();
        var enableCorsAttribute = new EnableCorsAttribute("*",
                                           "Origin, Content-Type, Accept",
                                           "GET, PUT, POST, DELETE, OPTIONS");
        config.EnableCors(enableCorsAttribute);
        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            //routeTemplate: "api/{controller}/{id}",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        config.Formatters.Add(new BrowserJsonFormatter());
    }

    public class BrowserJsonFormatter : JsonMediaTypeFormatter
    {
        public BrowserJsonFormatter()
        {
            this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
            this.SerializerSettings.Formatting = Formatting.Indented;
        }

        public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
        {
            base.SetDefaultContentHeaders(type, headers, mediaType);
            headers.ContentType = new MediaTypeHeaderValue("application/json");
        }
    }`
0
Yagnesh Khamar

Wenn Sie in Ihrer web.config über sicherheits\requestFiltering-Knoten verfügen, gehen Sie folgendermaßen vor:

<security>
  <requestFiltering>
    <verbs allowUnlisted="false">
      <add verb="GET" allowed="true" />
      <add verb="POST" allowed="true" />
      <add verb="PUT" allowed="true" />
      <add verb="DELETE" allowed="true" />
      <add verb="DEBUG" allowed="true" />          
    </verbs>
  </requestFiltering>

stellen Sie sicher, dass Sie dies auch hinzufügen

<add verb="OPTIONS" allowed="true" />
0
ozz