web-dev-qa-db-fra.com

ASP.NET WebApi: (405) Méthode non autorisée

J'ai un contrôleur Web Api. Il se comporte très étrange. Lorsque j'utilise PostMan, je peux accéder à la méthode POST sur l'API Web, mais lorsque j'utilise HttpWebRequest à partir de .net, elle retourne (405) Méthode non autorisée. Je mets le code de l'API Web ici:

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;

namespace MyProject.Controllers
{
    public class TestController : ApiController
    {
        [HttpPost]
        public int buy(OrderResult value)
        {
            try
            {
                if (value.InvoiceDate != null && value.Result == 1)
                {
                    return 0;
                }
            }
            catch{}

            return -1;
        }
    }

    public class OrderResult
    {
        public int Result { get; set; }
        public long InvoiceNumber { get; set; }
        public string InvoiceDate { get; set; }
        public long TimeStamp { get; set; }
    }
}

Voici mon WebApiConfig.cs:

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

namespace MyProject
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {

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

        }
    }
}

Voici comment j'envoie la demande POST d'un autre projet .NET:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;

namespace MyProject.Controllers
{
    public static class WebReq
    {
        public static string PostRequest(string Url, string postParameters)
        {
            try
            {
                HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(Url);
                myReq.Method = "POST";
                myReq.Timeout = 30000;
                myReq.Proxy = null;

                byte[] postData = Encoding.UTF8.GetBytes(postParameters);
                myReq.ContentLength = postData.Length;
                myReq.ContentType = "application/x-www-form-urlencoded";
                using (Stream requestWrite = myReq.GetRequestStream())
                {
                    requestWrite.Write(postData, 0, postData.Length);
                    requestWrite.Close();
                    using (HttpWebResponse webResponse = (HttpWebResponse)myReq.GetResponse())
                    {
                        if (webResponse.StatusCode == HttpStatusCode.OK)
                        {
                            using (Stream str = webResponse.GetResponseStream())
                            {
                                using (StreamReader sr = new StreamReader(str))
                                {
                                    return sr.ReadToEnd();
                                }
                            }
                        }
                        return null;
                    }
                }
            }
            catch (Exception e)
            {
                var message = e.Message;
                return null;
            }
        }

    }
}

J'ai déjà ajouté le code suivant dans mon web.config:

<modules runAllManagedModulesForAllRequests="true">
  <remove name="WebDAVModule" />
</modules>

C'est étrange parce que je peux envoyer la demande POST à partir de PostMan. Le PostMan envoie ce code à l'API.

POST /api/Test/buy HTTP/1.1
Host: domain.com
Cache-Control: no-cache
Postman-Token: 9220a4e6-e707-5c5f-ea61-55171a5dd95f
Content-Type: application/x-www-form-urlencoded

InvoiceDate=28012016&Result=1

J'apprécierai toute suggestion pour résoudre le problème.

6
TechTotal

J'ai trouvé la solution. 

J'ai vérifié la demande de Fiddler. Lorsque j'envoie une demande POST à l'API, celle-ci est automatiquement redirigée vers la même adresse avec ce nouveau paramètre AspxAutoDetectCookieSupport=1

Comment supprimer AspxAutoDetectCookieSupport = 1

Finalement, j'ai changé le cookieless="AutoDetect" dans web.config en cookieless="UseCookies" et le problème a été résolu.

2
TechTotal

Je sais que c'est un ancien post, mais peut-être que cela pourrait aider quelqu'un d'autre. Je viens d'avoir un problème similaire, obtenir une erreur 405 "Get not allowed" quand je faisais clairement un post dans le postier. En fait, je soumettais à l'URL en utilisant http au lieu de https. Passer à https a corrigé le problème.

3
Paul Reedy
     byte[] postData = Encoding.UTF8.GetBytes(postParameters);
            myReq.ContentLength = postData.Length;
            myReq.ContentType = "application/x-www-form-urlencoded";
            using (Stream requestWrite = myReq.GetRequestStream())
            {
                requestWrite.Write(postData, 0, postData.Length);

Il est fort probable que vous n'envoyiez pas une requête x-www-form-urlencoded appropriée. Il est probable que vous n'encodez pas correctement les données à partir de tout ce qui est passé en postParameters. Voir Publier des données de formulaire à l'aide de HttpWebRequest

Comme vous ne générez pas d'objet OrderResult valide selon x-www-form-urlencoded, le sélecteur de routage ne sélectionne pas votre action Buy. C'est pourquoi vous obtenez POST n'est pas autorisé.

Vous obtiendrez probablement le contrôleur si vous avez changé OrderResult value = null car il s'agit maintenant d'un paramètre facultatif. Cependant, ce n'est pas ce que vous voulez, sauf si vous allez avoir un contrôleur bizarre qui se comporte comme:

Buy(OrderResult value = null)
{
    if(value== null)
        value = MyCustomDeserializeFromRequestBody(RequestContext)

    ...
}

En fin de compte, vous ne devriez vraiment pas utiliser cette classe car il existe de bien meilleures constructions pour le développement moderne https://stackoverflow.com/a/31147762/37055https://github.com/hhariri/EasyHttp Du haut de ma tête

2
Chris Marisic