Casablanca: Problem mit WebAPI

Hallo,

ich habe da ein ziemlich großes Problem, an dem seit einem Tag arbeite und nicht weiterkomme. Ich habe einen APIController angelegt und versuche die CRUD-Methoden aus Views (form-Method oder ajax) heraus aufzurufen. Leider diese API-Methoden werden nicht gefunden oder habe ich die Meldung, dass mehrere Methoden infrage kommen, egal was ich da mache.

        [HttpPost]
        [Route("MyShop/Create")]
        public void Post(MyModel model)
        {

        }

        [HttpPost]
        [Route("MyShop/Edit")]
        public void Put(MyModel model, int? id)
        {
        }

        [HttpPost]
        [Route("MyShop/Delete")]
        public void Delete(int id)
        {
        }

Hat jemand da eine Idee?

Danke im Voraus.

  1. Tach!

    Ich habe einen APIController angelegt und versuche die CRUD-Methoden aus Views (form-Method oder ajax) heraus aufzurufen. Leider diese API-Methoden werden nicht gefunden oder habe ich die Meldung, dass mehrere Methoden infrage kommen, egal was ich da mache.

    Hast du MapHttpAttributeRoutes() aufgerufen? Das muss in der WebApiConfig.cs stehen, die sich in App_Start befindet, und vor dem config.Routes.MapHttpRoute(...). Also so:

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

    dedlfix.

    1. Hall.

      danke. Ja die beiden stehen genau so bereits drin. Ich verstehe nicht, warum ein Methodenaufruf so ein Problem verursacht. Ich sitze wirklich seit Stunden daran und bekomme dies nicht richtig hin. Das ist meine Form im View:

          @using (Html.BeginForm("Delete", "api/MyShop", FormMethod.Post, new { id = "delForm" }))
          {
              <div class="form-actions no-color">
                  <input type="submit" value="Delete" class="btn btn-default"/> |
              </div>
      
              @Html.Hidden("id", Model.Id)
          } 
      

      Ich finde im Netz auch nichts brauchbares.

      Gruß

      1. Tach!

        Ich verstehe nicht, warum ein Methodenaufruf so ein Problem verursacht.

        Vielleicht, weil api/MyShop ungleich MyShop ist?

        dedlfix.

        1. du meinst bei [Route("MyShop/Delete")]? Ich habe oben, oberhalb der Klasse den [RoutePrefix("api")] drin. So sollte funktionieren.

          {"Message":"Es wurde keine HTTP-Ressource gefunden, die mit dem Anforderungs-URI "http://localhost:10829/api/MyShop/Delete" übereinstimmt.","MessageDetail":"Für den Controller "MyShop" wurde keine Aktion gefunden, die mit der Anforderung übereinstimmt."}

          Gruß

          1. das hat anscheint wirklich mit dem Routen zu tun. Eine Delete-Methode ohne Parameter wird gefunden, eine mit id-Parameter nicht. Ich weiß auch nicht, warum die id nicht mitgeschickt wird, mit Post nicht und auch nicht mit Get.

          2. Tach!

            du meinst bei [Route("MyShop/Delete")]? Ich habe oben, oberhalb der Klasse den [RoutePrefix("api")] drin. So sollte funktionieren.

            Dann würde ich nun erstmal mit dem Fiddler (von Telerik) nachschauen, ob sich da was ergibt. Der nächste Schritt wäre, ein (Tutorial-)Projekt zu suchen, das auf dieselbe Weise funktioniert, dies zum Laufen zu bringen und dann zu schauen, wo die Unterschiede zu meinem Projekt sind.

            dedlfix.

            1. Hi,

              vielen Dank für deine Hilfe. Das Problem lag wohl daran, dass die View-Seite ein Object bekommen hat und wollte, warum auch immer, auch nur ein Objekt zurückgeben. Nachdem ich in der Delete-Methode "int id" mit einem Object vom Typ "MyModel model" ersetzt habe, funktioniert nun auch die Delete-Methode: Huuuuuh 😉

              Da habe ich aber noch zwei Fragen:

              1. Wie kann man nun aus der WebApi zurück zu einer beliebigen Seite springen? Ich muss ja nachdem ich z.B. etwas gelöscht/Editiert habe, wieder zu der Liste zurück.
              2. Wie kann ich eine Meldung über den Erfolg oder Misserfolg an die Seite übergeben. Hast du eventuell da Erfahrung?

              Danke im Voraus.

              1. Tach!

                1. Wie kann man nun aus der WebApi zurück zu einer beliebigen Seite springen? Ich muss ja nachdem ich z.B. etwas gelöscht/Editiert habe, wieder zu der Liste zurück.

                Das ist nicht Aufgabe der API, das muss dein Frontend regeln. Also der Teil, der die Daten an die API sendet (oder von dort holt), muss sich darum kümmern, dass die Anwendung sich entsprechend verhalten kann. Vermutlich indem er es an seinen Aufrufer weiterreicht, denn meist ist dieser Teil ein Service, der von irgendeiner Controller-Komponente angesprochen wird.

                1. Wie kann ich eine Meldung über den Erfolg oder Misserfolg an die Seite übergeben. Hast du eventuell da Erfahrung?

                Das ist Aufgabe desjenigen, der die API anspricht, oder oben genannten Service beauftragt, mit der API zu sprechen. Dieser Prozess muss das Ergebnis entgegennehmen und wie auch immer darstellen oder wohin auch immer weiterreichen.

                dedlfix.

                1. Hi,

                  danke. WebAPI-Methoden werden aus einer Seite heraus via Button-Klick und über einen form-Tag aufgerufen, die wiederum über einen Channel eine Methode aus dem Service aufrufen. Nun kann man ja eine Rückmeldung zwar an die WebAPI zurückgeben. Das ist aber auch alles. Die WebAPI muss diese ihrerseits auch weitergeben, ab wohin? Diese Meldung kann ja nicht eine eine form zurückgegeben werden. Wo kann man darauf reagieren?

                  Gruß

                  1. Tach!

                    WebAPI-Methoden werden aus einer Seite heraus via Button-Klick und über einen form-Tag aufgerufen, die wiederum über einen Channel eine Methode aus dem Service aufrufen. Nun kann man ja eine Rückmeldung zwar an die WebAPI zurückgeben. Das ist aber auch alles. Die WebAPI muss diese ihrerseits auch weitergeben, ab wohin? Diese Meldung kann ja nicht eine eine form zurückgegeben werden. Wo kann man darauf reagieren?

                    Die Web-API reagiert auf einen Request, tut damit irgendwas und erzeugt eine Response. Das übliche Verhalten von HTTP-basierten Systemen. Soweit die Server-Seite. Der clientseitige Prozess, der einen Request sendet, muss auch die Response entgegennehmen und verarbeiten. Das übliche Verhalten von HTTP-basierten Systemen. Anders als im herkömmlichen Browser-Verkehr werden Request zu APIs jedoch üblicherweise von einem Stück Javascript angestoßen worden. Und das muss sich auch um die Response kümmern.

                    Wenn du stattdessen den Browser einen kompletten Seitenaufruf machen lässt, ist ein API-Controller kein geeignetes Ziel dafür. Dann solltest du einen "normalen" Controller aufrufen und über eine View ein vollständiges Response-Dokument senden.

                    dedlfix.