web-dev-qa-db-fra.com

API MVC-Web: méthode 405 non autorisée

Donc, je suis coincé dans un comportement étrange, c’est-à-dire que je peux envoyer (ou poster) des données en utilisant Postman (plugin of chrome) ou en utilisant RESTClient(extension of Firefox)

enter image description here

mais pas en mesure de l'envoyer à partir de mon fichier HTML qui se trouve en dehors du projet. Il affiche l'erreur suivante lorsque j'ouvre le code HTML en chrome: 

OPTIONS http://localhost:1176/api/user/ 405 (Method Not Allowed)
XMLHttpRequest cannot load http://localhost:1176/api/user/. Invalid HTTP status code 405 

Je ne suis pas en mesure de comprendre pourquoi cela se produit. Voici les détails, vous devrez peut-être m'aider à résoudre mon erreur:

UserController.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WebAPIv2.Models;

namespace WebAPIv2.Controllers
{
    public class UserController : ApiController
    {
        static IUserRepository userRepository = new UserRepository();

        [HttpGet]
        public List<TableUser> GetAllUsers()
        {
            return userRepository.GetAll();
        }

        [HttpGet]
        public HttpResponseMessage GetUser(int id)
        {
            TableUser user = userRepository.Get(id);
            if (user == null)
            {
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, "User Not found for the Given ID");
            }

            else
            {
                return Request.CreateResponse(HttpStatusCode.OK, user);
            }
        }

        [HttpPost]
        public HttpResponseMessage PostUser(TableUser user)
        {
            user = userRepository.Add(user);
            var response = Request.CreateResponse<TableUser>(HttpStatusCode.Created, user);
            string uri = Url.Link("DefaultApi", new { id = user.UserId });
            response.Headers.Location = new Uri(uri);
            return response;
        }

        [HttpPut]
        public HttpResponseMessage PutUser(int id, TableUser user)
        {
            user.UserId = id;
            if (!userRepository.Update(user))
            {
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, "Unable to Update the User for the Given ID");
            }
            else
            {
                return Request.CreateResponse(HttpStatusCode.OK);
            }
        }

        [HttpDelete]
        public HttpResponseMessage DeleteProduct(int id)
        {
            userRepository.Remove(id);
            return new HttpResponseMessage(HttpStatusCode.NoContent);
        }
    }
}

User.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebAPIv2.Models
{
    public class User
    {
        public int UserId { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
    }
}

IUserRepository.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WebAPIv2.Models
{
    interface IUserRepository
    {
        List<TableUser> GetAll();
        TableUser Get(int id);
        TableUser Add(TableUser user);
        void Remove(int id);
        bool Update(TableUser user);
    }
}

UserRepository.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebAPIv2.Models
{
    public class UserRepository : IUserRepository
    {
        MastarsFriendsMVCDatabaseEntities userEntities;

        public UserRepository()
        {
            userEntities = new MastarsFriendsMVCDatabaseEntities();
        }

        public List<TableUser> GetAll()
        {
            //throw new NotImplementedException();

            return userEntities.TableUsers.ToList();
        }

        public TableUser Get(int id)
        {
            //throw new NotImplementedException();

            var users = userEntities.TableUsers.Where(x => x.UserId == id);
            if (users.Count() > 0)
            {
                return users.Single();
            }
            else
            {
                return null;
            }
        }

        public TableUser Add(TableUser user)
        {
            //throw new NotImplementedException();

            if (user == null)
            {
                throw new ArgumentNullException("item");
            }
            userEntities.TableUsers.Add(user);
            userEntities.SaveChanges();
            return user;
        }

        public void Remove(int id)
        {
            //throw new NotImplementedException();

            TableUser user = Get(id);
            if (user != null)
            {
                userEntities.TableUsers.Remove(user);
                userEntities.SaveChanges();
            }
        }

        public bool Update(TableUser user)
        {
            //throw new NotImplementedException();

            if (user == null)
            {
                throw new ArgumentNullException("student");
            }

            TableUser userInDB = Get(user.UserId);

            if (userInDB == null)
            {
                return false;
            }

            userEntities.TableUsers.Remove(userInDB);
            userEntities.SaveChanges();

            userEntities.TableUsers.Add(user);
            userEntities.SaveChanges();

            return true;
        }
    }
}

WebApiConfig.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Web.Http;

namespace WebAPIv2
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();
            //config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

index.html:

<!DOCTYPE html>
<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">

        <!--<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>-->
        <script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
    </head>
    <body>
        <script>
            $(document).ready(function() {
//                jQuery.support.cors = true;
//                $.ajax({
//                    url: "http://localhost:1176/api/user/1",
//                    headers: {"Accept": "application/json"},
//                    type: "GET",
//                    success: function(data) {
//                        alert(JSON.stringify(data));
//                    },
//                    error: function() {
//                        alert("Error");
//                    }
//                });
//            });

                var user = {
                    UserName: "Disha",
                    Password: "disha123",
                    FirstName: "Disha",
                    LastName: "Vora",
                    Email: "[email protected]"
                };

                $.ajax({
                    url: 'http://localhost:1176/api/user/',
                    type: 'POST',
                    data: JSON.stringify(user),
                    crossDomain: true,
                    headers: {"Accept":"application/json" , "Content-Type":"application/json"},
                    success: function(data) {
                        alert('User added Successfully');
                    },
                    error: function() {
                        alert('User not Added');
                    }
                });
            });
        </script>
    </body>
</html>

Web.config:

<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.Microsoft.com/fwlink/?LinkId=301879
  -->
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.Microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <appSettings></appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5">
      <assemblies>
        <add Assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      </assemblies>
    </compilation>
    <httpRuntime targetFramework="4.5" />
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="WebDAVModule" />
    </modules>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Request-Headers:" value="*" />
        <add name="Access-Control-Request-Method:" value="*" />
        <add name="Access-Control-Allow-Methods" value="*" />
        <!--<add name="Allow" value="*"/>-->
      </customHeaders>
    </httpProtocol>
    <handlers>
      <remove name="WebDAV" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
    <directoryBrowse enabled="true" />
  </system.webServer>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
  </entityFramework>
  <connectionStrings>
    <add name="MastarsFriendsMVCDatabaseEntities" connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=WIN-WWU3DMLR6PX\PIXIELIT;initial catalog=MastarsFriendsMVCDatabase;persist security info=True;user id=sa;password=sa_12345;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>
</configuration>
11
Chintan Soni

WebApi bloque probablement la demande CORS. Pour activer CORS sur WebApi, utilisez le package Microsoft.AspNet.WebApi.Cors. Pour plus d'informations, consultez http://www.asp.net/web-api/overview/security/enabling-cross-Origin-requests-in-web-api

17
martennis

D'accord. Résolu le problème avec l'aide de @martennis, mais avec une petite correction.

Pour que tout soit parfait, il suffit d'entrer la commande suivante dans la console de gestion de package:

Install-Package Microsoft.AspNet.WebApi.Cors –IncludePrerelease

Au lieu de celle indiquée dans le lien fourni par, @martennis, et après cela, mon WebApiConfig.cs a été mis à jour comme suit:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Web.Http.Cors;

namespace WebApiRESTfulwithJSON
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            var cors = new EnableCorsAttribute("*", "*", "*");
            config.EnableCors(cors);

            // Web API routes
            config.MapHttpAttributeRoutes();

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

Par conséquent, résolu le problème ... !!!

Maintenant, je pourrai utiliser mes services Web de n'importe où, en l'appelant depuis des applications mobiles, des applications Web ou des applications de bureau.

Car, comment les créer à partir de rien, j’ai écrit mon premier blog à ce sujet (... malgré le fait d’être développeur Android, je n’ai jamais essayé d’écrire un blog pour Android:

Lien: http://programmingwithease.wordpress.com/2014/06/18/learning-asp-net-web-api-2-using-c/

25
Chintan Soni

La suppression de "using System.Web.MVC" de la classe de contrôleur a résolu ce problème pour moi.

0
user1892777

Pas besoin de webconfig, tout ce dont vous avez besoin est d'ajouter:

  services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
            {
                builder.AllowAnyOrigin()
                       .AllowAnyMethod()
                       .AllowAnyHeader();
            }));
0
Joseph