534 Stimmen

Übergabe eines Arrays von Ganzzahlen an ASP.NET Web API?

Ich habe einen ASP.NET Web API (Version 4) REST-Dienst, wo ich ein Array von Ganzzahlen übergeben müssen.

Hier ist meine Aktionsmethode:

public IEnumerable<Category> GetCategories(int[] categoryIds){
// code to retrieve categories from database
}

Und dies ist die URL, die ich ausprobiert habe:

/Categories?categoryids=1,2,3,4

751voto

Lavel Punkte 7400

Sie müssen nur Folgendes hinzufügen [FromUri] vor dem Parameter, sieht so aus:

GetCategories([FromUri] int[] categoryIds)

Und Anfrage senden:

/Categories?categoryids=1&categoryids=2&categoryids=3

117voto

Mrchief Punkte 72978

Comme Philipp W weist darauf hin, dass Sie möglicherweise auf einen benutzerdefinierten Modellbinder wie diesen zurückgreifen müssen (modifiziert, um an den tatsächlichen Typ des Parameters zu binden):

public IEnumerable<Category> GetCategories([ModelBinder(typeof(CommaDelimitedArrayModelBinder))]long[] categoryIds) 
{
    // do your thing
}

public class CommaDelimitedArrayModelBinder : IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        var key = bindingContext.ModelName;
        var val = bindingContext.ValueProvider.GetValue(key);
        if (val != null)
        {
            var s = val.AttemptedValue;
            if (s != null)
            {
                var elementType = bindingContext.ModelType.GetElementType();
                var converter = TypeDescriptor.GetConverter(elementType);
                var values = Array.ConvertAll(s.Split(new[] { ","},StringSplitOptions.RemoveEmptyEntries),
                    x => { return converter.ConvertFromString(x != null ? x.Trim() : x); });

                var typedValues = Array.CreateInstance(elementType, values.Length);

                values.CopyTo(typedValues, 0);

                bindingContext.Model = typedValues;
            }
            else
            {
                // change this line to null if you prefer nulls to empty arrays 
                bindingContext.Model = Array.CreateInstance(bindingContext.ModelType.GetElementType(), 0);
            }
            return true;
        }
        return false;
    }
}

Und dann können Sie sagen:

/Categories?categoryids=1,2,3,4 und ASP.NET Web API binden korrekt Ihre categoryIds Array.

47voto

Steve Czetty Punkte 6087

Ich bin vor kurzem selbst auf diese Anforderung gestoßen und habe beschlossen, eine ActionFilter um dies zu handhaben.

public class ArrayInputAttribute : ActionFilterAttribute
{
    private readonly string _parameterName;

    public ArrayInputAttribute(string parameterName)
    {
        _parameterName = parameterName;
        Separator = ',';
    }

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (actionContext.ActionArguments.ContainsKey(_parameterName))
        {
            string parameters = string.Empty;
            if (actionContext.ControllerContext.RouteData.Values.ContainsKey(_parameterName))
                parameters = (string) actionContext.ControllerContext.RouteData.Values[_parameterName];
            else if (actionContext.ControllerContext.Request.RequestUri.ParseQueryString()[_parameterName] != null)
                parameters = actionContext.ControllerContext.Request.RequestUri.ParseQueryString()[_parameterName];

            actionContext.ActionArguments[_parameterName] = parameters.Split(Separator).Select(int.Parse).ToArray();
        }
    }

    public char Separator { get; set; }
}

Ich wende es wie folgt an (beachten Sie, dass ich "id" und nicht "ids" verwendet habe, da es in meiner Route so angegeben ist):

[ArrayInput("id", Separator = ';')]
public IEnumerable<Measure> Get(int[] id)
{
    return id.Select(i => GetData(i));
}

Und die öffentliche Url würde lauten:

/api/Data/1;2;3;4

Möglicherweise müssen Sie dies an Ihre speziellen Bedürfnisse anpassen.

30voto

Sofija Punkte 713

Für den Fall, dass jemand dasselbe oder etwas Ähnliches (z. B. Löschen) erreichen möchte über POST anstelle von FromUri verwenden FromBody und auf der Client-Seite (JS/jQuery) formatieren Sie param als $.param({ '': categoryids }, true)

c#:

public IHttpActionResult Remove([FromBody] int[] categoryIds)

jQuery:

$.ajax({
        type: 'POST',
        data: $.param({ '': categoryids }, true),
        url: url,
//...
});

Die Sache mit $.param({ '': categoryids }, true) ist, dass .net erwartet, dass der Postkörper einen urlencodierten Wert wie =1&=2&=3 ohne Parametername und ohne Klammern.

29voto

Jignesh Variya Punkte 1729

Einfache Möglichkeit, Array-Parameter an Web-Api zu senden

API

public IEnumerable<Category> GetCategories([FromUri]int[] categoryIds){
 // code to retrieve categories from database
}

Jquery: JSON-Objekt als Anfrage-Parameter senden

$.get('api/categories/GetCategories',{categoryIds:[1,2,3,4]}).done(function(response){
console.log(response);
//success response
});

Die URL Ihrer Anfrage wird wie folgt generiert ../api/categories/GetCategories?categoryIds=1&categoryIds=2&categoryIds=3&categoryIds=4

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X