web-dev-qa-db-ger.com

Azure Custom Controller/API .Net-Backend

Ich habe einen MobileService auf Azure ausgeführt und habe beschlossen, einen neuen Dienst zu erstellen und den Code selbst zu migrieren. Der neue Dienst hat den neuen Typ "Azure Mobile App Service".

Zur Zeit habe ich Authentifizierung und kann Migrationen/Update-Datenbanken ausführen. Ich folge dem TodoItem-Beispiel. Ich möchte jetzt eine eigene benutzerdefinierte API erstellen, die problemlos mit MobileService funktioniert, aber ich kann sie nicht mit der Azure Mobile App verwenden: /

Ich habe diese beiden Links Web-Api-Routing und App-Service-Mobile-Backend verfolgt. Und ich habe jetzt folgendes:

Ich habe einen neuen Controller erstellt:

[MobileAppController]
public class TestController : ApiController
{
    // GET api/Test
    [Route("api/Test/completeAll")]
    [HttpPost]
    public async Task<ihttpactionresult> completeAll(string info)
    {
        return Ok(info + info + info);
    }
}

In der mobileApp.cs habe ich den folgenden Code gemäß Backend hinzugefügt:

HttpConfiguration config = new HttpConfiguration();
config.MapHttpAttributeRoutes();

Zusätzlich habe ich das folgende Paket gemäß web-api-routing installiert:

Microsoft.AspNet.WebApi.WebHost 

und der Anruf vom Kunden:

string t = await App.MobileService.InvokeApiAsync<string,string>("Test/completeAll", "hej");

Debug zeigt, dass es sich um die richtige URL handelt:

{Methode: POST, RequestUri: ' https://xxxxxxx.azurewebsites.net/api/Test/completeAll ', Version: 1.1, Inhalt: System.Net.Http.StringContent, Header: {X-ZUMO-FEATURES: AT X-ZUMO-INSTALLATIONS-ID: e9b359df-d15e-4119-a4ad-afe3031d8cd5 X-ZUMO-AUTH: xxxxxxxxxxx Akzeptieren: application/json User-Agent: ZUMO/2.0 User-Agent: (lang = verwaltet; os = Windows Store; os_version = -; Arch = neutral; Version = 2.0.31125.0) X-ZUMO-VERSION: ZUMO/2.0 (lang = verwaltet; os = Windows Store; os_version = -; arch = neutral; version = 2.0.31125.0) ZUMO-API-VERSION: 2.0.0 Inhaltstyp: application/json; charset = utf-8 Inhaltslänge: 3}}

Erhalten Sie jedoch folgende Informationen: 404 (Nicht gefunden) Debug-Nachricht "Die Anforderung konnte nicht abgeschlossen werden. (Nicht gefunden)"

Was vermisse ich :/ ?

Update

Ich habe versucht, den Code in Die mobileApp.cs zu erweitern:

HttpConfiguration config = new HttpConfiguration();
        new MobileAppConfiguration()
            .UseDefaultConfiguration().MapApiControllers()
            .ApplyTo(config);
        config.MapHttpAttributeRoutes();
        app.UseWebApi(config);

basierend auf app-service-backend , jedoch noch kein Zugriff: /

Aktualisieren

Ich habe fiddler2 verwendet, um über einen Browser auf den Endpunkt zuzugreifen, und erhielt folgende Ergebnisse:

 Fiddler output

Update erneut

Ich habe versucht, eine andere Minimallösung zu erstellen, bekomme aber immer noch den gleichen Fehler. Gibt es tolle Tutorials, denen ich folgen kann, um diese Funktionalität zu erreichen? 

Das positive Gefühl verdampft langsam. . . 

Die Frage läuft jetzt auch auf msdn , ich werde hier aktualisieren, wenn dort Informationen angezeigt werden.


Aktualisieren

Getesteter Lindas Kommentar, und ich kann tatsächlich auf den Wertkonverter zugreifen:

// Use the MobileAppController attribute for each ApiController you want to use  
// from your mobile clients 
[MobileAppController]
public class ValuesController : ApiController
{
    // GET api/values
    public string Get()
    {
        MobileAppSettingsDictionary settings = this.Configuration.GetMobileAppSettingsProvider().GetMobileAppSettings();
        ITraceWriter traceWriter = this.Configuration.Services.GetTraceWriter();

        string Host = settings.HostName ?? "localhost";
        string greeting = "Hello from " + Host;

        traceWriter.Info(greeting);
        return greeting;
    }

    // POST api/values
    public string Post()
    {
        return "Hello World!";
    }

}

Auf diese habe ich mit der Post- und Get-Funktion zugegriffen:

string t = await App.MobileService.InvokeApiAsync<string, string>("values", null, HttpMethod.Post, null);

oder

string t = await App.MobileService.InvokeApiAsync<string, string>("values", null, HttpMethod.Get, null);

Der eingefügte Code hat jedoch keine Route. Warum kann ich mit Werten darauf zugreifen? Was wäre der Pfad zum ursprünglichen Controller, wenn der Routenparameter nicht verwendet würde?


Zusatzinformation

Ich habe jetzt ein Support-Ticket mit Microsoft erstellt und werde es mit zusätzlichen Informationen aktualisieren. . . Hoffnungsvoll.

Update Info vom MSDN-Forum: MS_SkipVersionCheck Versuchen. Das Lesen des Attributs here scheint nicht zutreffend zu sein. Aber ich habe es versucht. Noch Not Found für meine API, aber das Original funktioniert noch. Es hatte also keinen Einfluss auf dieses Problem.

31
JTIM

Ja !!!

Also habe ich es endlich zum Laufen gebracht, die Usings von lidydonna - msft git kopiert und von .net Backend für Mobileservice gelesen.

Dies endete mit folgendem:

using System.Web.Http;
using Microsoft.Azure.Mobile.Server.Config;
using System.Threading.Tasks;
using System.Web.Http.Tracing;
using Microsoft.Azure.Mobile.Server;

namespace BCMobileAppService.Controllers
{
[MobileAppController]
public class TestController : ApiController
{
    // GET api/Test
    [HttpGet, Route("api/Test/completeAll")]
    public string Get()
    {
        MobileAppSettingsDictionary settings = this.Configuration.GetMobileAppSettingsProvider().GetMobileAppSettings();
        ITraceWriter traceWriter = this.Configuration.Services.GetTraceWriter();

            string Host = settings.HostName ?? "localhost";
            string greeting = "Hello from " + Host;

            traceWriter.Info(greeting);
            return greeting;
        }

        // POST api/values
        [HttpPost, Route("api/Test/completeAll")]
        public string Post(string hej)
        {
            string retVal = "Hello World!" + hej;
            return retVal;
        }
    }
}

Dies ist ein neuer Controller und nicht der, der als Lidydonna verwendet wird. Es schien, als wollte es beide Funktionen get und post. Dies führte dazu, dass die API registriert wurde und auf die zugegriffen werden konnte. Dies bedeutet, dass der Clientaufruf an den Server, den ich verwendete, Folgendes war:

t = await App.MobileService.InvokeApiAsync<string, string>("Test/completeAll", null, HttpMethod.Post, new Dictionary<string, string>() { { "hej", " AWESOME !" }});

dialog = new MessageDialog(t);
dialog.Commands.Add(new UICommand("OK"));
await dialog.ShowAsync();

Und ich bekam eine Antwort YAY !!

Zusatzinformation

Die von Ihnen erstellten Controller, d. H. Die Klasse muss mit Controller enden, Sie können Text vor, aber nicht danach haben. Diese Informationen wurden in einer MSDN-Forum-Diskussion gegeben.

Wenn post und get die gleiche Eingabe haben, gibt der Server Not found zurück. Unterschiedliche Eingaben lösen das Problem.

Im Falle von seltsamem Internal Server Error, d. H. Seltsam, können Sie den gesamten Servercode schrittweise durchlaufen. Alle Variablen, die Sie zurückgeben möchten, werden initialisiert, der Client erhält jedoch den Fehler. Weitere Informationen finden Sie unter Interner Serverfehler - Benutzerdefinierter Azure App Service-Controller , wo das Problem durch eine einfache Korrektur der Konfiguration behoben werden kann.

15
JTIM

Es muss etwas in Ihrer Projektkonfiguration falsch sein. Ich habe hier eine Arbeitsprobe: https://Gist.github.com/lindydonna/6fca7f689ee72ac9cd20

Rufen Sie nach dem Erstellen des HttpConfiguration-Objekts config.MapHttpAttributeRoutes() auf. Ich habe das Routenattribut [Route("api/Test/completeAll")] hinzugefügt und kann bestätigen, dass die Route korrekt registriert ist.

Fügen Sie dieses Attribut dem ValuesController hinzu und überprüfen Sie die Route.

5
lindydonna

Ich habe eine andere Ursache für die 404-Fehler gefunden, als das Attribut-Routing verwendet wurde.

Der obige Code hatte ursprünglich Folgendes in mobileApp.cs:

HttpConfiguration config = new HttpConfiguration();
    new MobileAppConfiguration()
        .UseDefaultConfiguration().MapApiControllers()
        .ApplyTo(config);
    config.MapHttpAttributeRoutes();
    app.UseWebApi(config);

Das config.MapHttpAttributeRoutes () muss über das .ApplyTo verschoben werden:

HttpConfiguration config = new HttpConfiguration();
 config.MapHttpAttributeRoutes();
 new MobileAppConfiguration()
        .UseDefaultConfiguration().MapApiControllers()
        .ApplyTo(config);
2
mdorson

Es ist wirklich merkwürdig, aber die einfache API-Anforderung funktioniert nicht im Azure-App-Service .__ Ich habe also herausgefunden, welche Lösung für mich funktioniert hat. Ich habe http-Anfragen mit c # http post/get, Android post/get und Objective C post/get .__ getestet. Zuerst müssen Sie Ihre Startup.MobileApp.cs-Klasse aktualisieren: 

  new MobileAppConfiguration()
    .UseDefaultConfiguration()   
    .MapApiControllers()                /* /api endpoints **missing part***/ 
    .ApplyTo(config);

Erstellen Sie anschließend einen benutzerdefinierten Controller für Azure Mobile App. Danach modifizieren Sie den Controller ein wenig, um die richtige Json-Antwort zu erhalten

    public class Mes
    {
        public string message { get; set; }
    }

    // GET api/My
    public Mes Get()
    {

        return new Mes { message = "thanks" };


       // return "Hello from custom controller!";
    }
    // POST api/My
    public Mes Post(Mes chal)
    {

        return new Mes { message = chal.message + "asnwer" };


        // return "Hello from custom controller!";
    }
}

Sie können die erste Variante einfach verlassen und erhalten eine Antwort, aber Ziel C wird Ihnen sagen, dass JSON-Text nicht mit Array oder Objekt und der Option zum Zulassen von Fragmenten ... usw. beginnt. Dies geschieht, weil Sie einfach werden Zeichenfolge nicht Objekt Aus diesem Grund habe ich meine Antwort mit der Klasse Mes .__ geändert. Es hängt jedoch auch davon ab, wie Sie eine Anforderung stellen und welche Art von Objekt Sie erwarten. .MapApiControllers () ist also der Hauptschlüssel für die API, und der WEB-API-Controller wird jetzt in einen benutzerdefinierten Azure-Controller geändert. __ Ich hoffe, das hilft. 

1

Versuchen Sie, das Erben von ApiController auf TableController umzustellen.

1
viktorh