it-swarm.com.de

Wie muss ich mehrere Parameter an ein ASP.Net Web API GET übergeben?

Ich verwende die .Net MVC4-Web-API, um (hoffentlich) eine RESTful-API zu implementieren. Ich muss einige Parameter an das System übergeben und einige Aktionen ausführen lassen, um dann eine Liste von Objekten als Ergebnis zurückzugeben. Ich gebe gerade zwei Daten ein und gebe Datensätze zurück, die zwischen ihnen liegen. Ich verfolge auch die zurückgegebenen Datensätze, damit nachfolgende Anrufe im System nicht erneut verarbeitet werden.

Ich habe ein paar Ansätze überlegt:

  1. Die Parameter werden in eine einzige JSON-Zeichenfolge serialisiert und in der API getrennt . http://forums.asp.net/t/1807316.aspx/1

  2. Übergeben Sie die Parameter in der Abfragezeichenfolge.
    Wie lassen sich mehrere Abfrageparameter am besten an eine restliche API übergeben?

  3. Definieren der Parameter in der Route: Api/controller/date1/date2

  4. Mit einem POST kann ich von Natur aus ein Objekt mit Params übergeben.

  5. Recherchiert ODATA seit der Web-API (derzeit) unterstützt. Ich habe damit noch nicht viel gemacht, daher bin ich damit nicht sehr vertraut.

Es scheint, dass korrekte REST -Praktiken darauf hinweisen, dass beim Abrufen von Daten ein GET verwendet werden sollte. GET sollte jedoch auch nullipotent sein (erzeugt keine Nebeneffekte), und ich frage mich, ob meine spezifische Implementierung gegen das verstößt, seit ich Datensätze im API-System markiere. Daher produziere ich Nebeneffekte.

Es brachte mich auch zur Frage der Unterstützung variabler Parameter. Wenn sich die Liste der Eingabeparameter ändert, wäre es mühsam, Ihre Route für Choice 3 neu definieren zu müssen, wenn dies häufig geschieht. Und was passiert, wenn die Parameter zur Laufzeit definiert werden ...

Welche Wahl (falls zutreffend) erscheint mir für meine konkrete Implementierung am besten?

119
sig606

Was bedeutet diese Rekordmarkierung? Wenn dies nur zu Protokollierungszwecken verwendet wird, würde ich GET verwenden und das Caching deaktivieren, da Sie jede Abfrage für diese Ressourcen protokollieren möchten. Wenn die Datensatzmarkierung einen anderen Zweck hat, ist POST der richtige Weg. Der Benutzer sollte wissen, dass seine Aktionen das System beeinflussen, und die Methode POST ist eine Warnung.

10
LukLed

Ich denke, der einfachste Weg ist, einfach AttributeRouting zu verwenden.

In Ihrem Controller ist es offensichtlich, warum sollten Sie dies in Ihrer globalen WebApiConfig-Datei haben?

Beispiel:

    [Route("api/YOURCONTROLLER/{paramOne}/{paramTwo}")]
    public string Get(int paramOne, int paramTwo)
    {
        return "The [Route] with multiple params worked";
    }

Die {}-Namen müssen mit Ihren Parametern übereinstimmen. 

So einfach ist das, jetzt haben Sie eine separate GET, die in dieser Instanz mehrere Parameter behandelt.

Fügen Sie einfach eine neue Route zu den WebApiConfig-Einträgen hinzu.

Zum Beispiel anrufen:

public IEnumerable<SampleObject> Get(int pageNumber, int pageSize) { ..

hinzufügen:

config.Routes.MapHttpRoute(
    name: "GetPagedData",
    routeTemplate: "api/{controller}/{pageNumber}/{pageSize}"
);

Fügen Sie dann die Parameter zum HTTP-Aufruf hinzu:

GET //<service address>/Api/Data/2/10 
48
Graham Wright

Ich musste nur eine RESTfull-API implementieren, bei der ich Parameter übergeben muss. Ich habe dies getan, indem ich die Parameter in der Abfragezeichenfolge im selben Stil übergeben habe, wie er in Marks erstem Beispiel "api/controller? Start = date1 & end = date2" beschrieben ist.

Im Controller habe ich einen Tipp von URL in C # verwendet?

// uri: /api/courses
public IEnumerable<Course> Get()
{
    NameValueCollection nvc = HttpUtility.ParseQueryString(Request.RequestUri.Query);
    var system = nvc["System"];
    // BL comes here
    return _courses;
}

In meinem Fall rief ich den WebApi über Ajax an und sah folgendermaßen aus:

$.ajax({
        url: '/api/DbMetaData',
        type: 'GET',
        data: { system : 'My System',
                searchString: '123' },
        dataType: 'json',
        success: function (data) {
                  $.each(data, function (index, v) {
                  alert(index + ': ' + v.name);
                  });
         },
         statusCode: {
                  404: function () {
                       alert('Failed');
                       }
        }
   });

Ich hoffe das hilft...

44
Nigel Findlater

Ich habe eine ausgezeichnete Lösung gefunden auf http://habrahabr.ru/post/164945/

public class ResourceQuery
{
   public string Param1 { get; set; }
   public int OptionalParam2 { get; set; }
}

public class SampleResourceController : ApiController
{
    public SampleResourceModel Get([FromUri] ResourceQuery query)
    {
        // action
    }
}
37
Andrew Veriga

Die Verwendung von GET oder POST wird durch @LukLed eindeutig erklärt. In Bezug auf die Möglichkeiten, wie Sie die Parameter übergeben können, würde ich vorschlagen, mit dem zweiten Ansatz zu arbeiten (ich weiß auch nicht viel über ODATA).

1.Serialisierung der Parameter in eine einzige JSON-Zeichenfolge und Auswahl in der API. http://forums.asp.net/t/1807316.aspx/1

Dies ist nicht benutzerfreundlich und SEO-freundlich

2.Pass die Parameter in der Abfragezeichenfolge. Was ist der beste Weg, um mehrere Abfrageparameter an eine restful API zu übergeben?

Dies ist der übliche bevorzugte Ansatz.

3. Definieren der Parameter in der Route: API/Controller/Datum1/Datum2

Dies ist definitiv kein guter Ansatz. Dies macht das Gefühl, dass date2 eine Subressource von date1 ist, und das ist nicht der Fall. Sowohl date1 als auch date2 sind Abfrageparameter und liegen in derselben Ebene.

Im einfachen Fall würde ich eine solche URI vorschlagen,

api/controller?start=date1&end=date2

Ich persönlich mag das untenstehende URI-Muster, aber in diesem Fall müssen wir benutzerdefinierten Code schreiben, um die Parameter zuzuordnen.

api/controller/date1,date2
8
VJAI
8
danan
 [Route("api/controller/{one}/{two}")]
    public string Get(int One, int Two)
    {
        return "both params of the root link({one},{two}) and Get function parameters (one, two)  should be same ";
    }

Beide Parameter des Root-Links ({one}, {two}) und der Get-Funktionsparameter (Eins, Zwei) sollten identisch sein

2
ashwath hegde
    public HttpResponseMessage Get(int id,string numb)
    {
        //this will differ according to your entity name
        using (MarketEntities entities = new MarketEntities())
        {
          var ent=  entities.Api_For_Test.FirstOrDefault(e => e.ID == id && e.IDNO.ToString()== numb);
            if (ent != null)
            {
                return Request.CreateResponse(HttpStatusCode.OK, ent);
            }
            else
            {
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, "Applicant with ID " + id.ToString() + " not found in the system");
            }
        }
    }
0
Jesse Mwangi

Mit .Net Core kann man wie folgt vorgehen.

    [Route("api/[controller]")]
    [ApiController]
    public class ReportController : ControllerBase
    {
...
...        
        // GET api/report/5454510/10/abc
        [HttpGet("{id}/{page}/{etc}")]
        public async Task<ActionResult<string>> Get(string id, int page, string etc)
0
DineshNS

Ich weiß, das ist wirklich alt, aber ich wollte das Gleiche vor kurzem und hier ist, was ich gefunden habe ...

    public HttpResponseMessage Get([FromUri] string var, [FromUri] string test) {
        var retStr = new HttpResponseMessage(HttpStatusCode.OK);
        if (var.ToLower() == "getnew" && test.ToLower() == "test") {
            retStr.Content = new StringContent("Found Test", System.Text.Encoding.UTF8, "text/plain");
        } else {
            retStr.Content = new StringContent("Couldn't Find that test", System.Text.Encoding.UTF8, "text/plain");
        }

        return retStr;
    }

Also jetzt in deiner Adresse/URI/...

http (s): // myURL/api/myController /? var = getnew & test = test

Ergebnis: "Found Test"


http (s): // myURL/api/myController /? var = getnew & test = irgendetwas

Ergebnis: "Konnte diesen Test nicht finden"

0
Rick Riggs