Perkelkite sveikų skaičių masyvą į ASP.NET Web API?

Turiu ASP.NET Web API REST paslaugą (4 versija), kur turiu perduoti sveikų skaičių skaičių.

Čia yra mano veiksmų metodas:

 /Categories?categoryids=1,2,3,4 
289
02 апр. Hemanshu Bhojak rinkinys 02 Bal 2012-04-02 20:58 '12, 20:58, 2012-04-02 20:58
@ 14 atsakymų

Prieš parametrą reikia pridėti [FromUri] , tai atrodo taip:

Ir siųskite užklausą:

 /Categories?categoryids=1> 
443
19 июня '12 в 14:57 2012-06-19 14:57 atsakymą pateikė Lavelas birželio 19 d. 12 val. 14:57 2012-06-19 14:57

Kaip nurodo Filip W , jums gali tekti kreiptis į pasirinktinį modelio sub-objektą (modifikuotas, kad prisijungtų prie faktinio parametrų tipo):

 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; } } 

Ir tada galite pasakyti:

/Categories?categoryids=1,2,3,4 , o ASP.NET Web API teisingai susieja jūsų categoryIds .

82
01 окт. atsakymas suteiktas Mrchief Oct 01 2013-10-01 07:02 '13, 07:02 am 2013-10-01 07:02

Neseniai aš pats įvykdžiau šį reikalavimą ir nusprendžiau įgyvendinti „ ActionFilter “.

 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; } } 

Aš tai naudoju (atkreipkite dėmesį, kad naudoju „id“, o ne „identifikatorius“, kaip nurodyta mano maršrute):

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

Ir viešasis URL atrodys taip:

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

Gali prireikti pertvarkyti, kad atitiktų jūsų konkrečius poreikius.

30
09 июля '13 в 19:19 2013-07-09 19:19 atsakymas pateikiamas Steve Czetty liepos 9 d., 13 val. 19:19 2013-07-09 19:19

Jei kas nors to reikia - norint pasiekti tą patį ar panašų dalyką (pvz., Ištrinti), naudojant POST o ne FromUri naudokite FromBody ir kliento pusėje (JS / jQuery) kaip $.param({ '': categoryids }, true)

Su #:

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

Jquery

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

Su $.param({ '': categoryids }, true) dalykas yra tai, kad ji .net tikisi, kad pranešimo kūno sudėtyje bus urlencoded tipo tipas =1> be parametro pavadinimo ir be skliaustų.

15
13 марта '15 в 11:46 2015-03-13 11:46 atsakymas duotas Sofijai kovo 15 d. 15 val. 11:46 2015-03-13 11:46

Paprastas būdas siųsti masyvo parametrus žiniatinklio api

API

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

JQuery: siųsti JSON objektą kaip užklausos parametrus

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

Jis generuos jūsų užklausos URL, pvz., ../api/categories/GetCategories?categoryIds=1>

11
05 апр. Atsakymą pateikė Jignesh Variya 05 Bal. 2017-04-05 13:28 '17 at 13:28 2017-04-05 13:28

Galite išbandyti šį kodą taip, kad galėtumėte priimti kableliais atskirtas reikšmes / reikšmių masyvą, kad grįžtumėte JSON iš webAPI

9
03 апр. Atsakymą pateikė Naveen Vijay 03 Bal. 2012-04-03 22:25 '12, 10:25 val. 2012-04-03 22:25

Jei norite, kad sveikų skaičių sąrašas / masyvas būtų paprasčiausias būdas, paimkite kableliais atskirtą (,) styginių sąrašą ir konvertuokite jį į sveikųjų skaičių sąrašą. Nepamirškite paminėti [FromUri] attriubte.your URL atrodo

?

... ID = 71 AccountId = 1,2,3,289,56

 public HttpResponseMessage test([FromUri]int ID, [FromUri]string accountID) { List<int> accountIdList = new List<int>(); string[] arrAccountId = accountId.Split(new char[] { ',' }); for (var i = 0; i < arrAccountId.Length; i++) { try { accountIdList.Add(Int32.Parse(arrAccountId[i])); } catch (Exception) { } } } 
5
04 авг. atsakymą pateikė Vaibhav 04 rug. 2015-08-04 11:30 '15, 11:30, 2015-08-04 11:30
 public class ArrayInputAttribute : ActionFilterAttribute { private readonly string[] _ParameterNames; /// <summary> /// /// </summary> public string Separator { get; set; } /// <summary> /// cons /// </summary> /// <param name="parameterName"></param> public ArrayInputAttribute(params string[] parameterName) { _ParameterNames = parameterName; Separator = ","; } /// <summary> /// /// </summary> public void ProcessArrayInput(HttpActionContext actionContext, string parameterName) { if (actionContext.ActionArguments.ContainsKey(parameterName)) { var parameterDescriptor = actionContext.ActionDescriptor.GetParameters().FirstOrDefault(p => p.ParameterName == parameterName); if (parameterDescriptor != null  parameterDescriptor.ParameterType.IsArray) { var type = parameterDescriptor.ParameterType.GetElementType(); var parameters = String.Empty; if (actionContext.ControllerContext.RouteData.Values.ContainsKey(parameterName)) { parameters = (string)actionContext.ControllerContext.RouteData.Values[parameterName]; } else { var queryString = actionContext.ControllerContext.Request.RequestUri.ParseQueryString(); if (queryString[parameterName] != null) { parameters = queryString[parameterName]; } } var values = parameters.Split(new[] { Separator }, StringSplitOptions.RemoveEmptyEntries) .Select(TypeDescriptor.GetConverter(type).ConvertFromString).ToArray(); var typedValues = Array.CreateInstance(type, values.Length); values.CopyTo(typedValues, 0); actionContext.ActionArguments[parameterName] = typedValues; } } } public override void OnActionExecuting(HttpActionContext actionContext) { _ParameterNames.ForEach(parameterName => ProcessArrayInput(actionContext, parameterName)); } } 

Naudoti:

  [HttpDelete] [ArrayInput("tagIDs")] [Route("api/v1/files/{fileID}/tags/{tagIDs}")] public HttpResponseMessage RemoveFileTags(Guid fileID, Guid[] tagIDs) { _FileRepository.RemoveFileTags(fileID, tagIDs); return Request.CreateResponse(HttpStatusCode.OK); } 

Prašymas uri

 http://localhost/api/v1/files/2a9937c7-8201-59b7-bc8d-11a9178895d0/tags/BBA5CD5D-F07D-47A9-8DEE-D19F5FA65F63,BBA5CD5D-F07D-47A9-8DEE-D19F5FA65F63 
4
15 июля '14 в 8:04 2014-07-15 08:04 atsakymas pateikiamas Waninlezu'ui liepos 14 d. 14 d. 8:04 2014-07-15 08:04

Atlikite metodo tipą [HttpPost], sukurkite modelį su vienu int [] parametru ir siųskite žinutę naudodami json:

  public class CategoryRequestModel { public int[] Categories { get; set; } }  [HttpPost] public HttpResponseMessage GetCategories(CategoryRequestModel model) { HttpResponseMessage resp = null; try { var categories = //your code to get categories resp = Request.CreateResponse(HttpStatusCode.OK, categories); } catch(Exception ex) { resp = Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex); } return resp; }  var ajaxSettings = { type: 'POST', url: '/Categories', data: JSON.serialize({Categories: [1,2,3,4]}), contentType: 'application/json', success: function(data, textStatus, jqXHR) { //get categories from data } }; $.ajax(ajaxSettings); 
3
10 июня '16 в 18:50 2016-06-10 18:50 atsakymas pateikiamas koduMonkey birželio 10 d. 16, 18:50 2016-06-10 18:50

Arba galite tiesiog perduoti atskirų elementų eilutę ir įdėti jį į masyvą arba sąrašą priimančioje pusėje.

1
30 авг. atsakymą pateikė Sirentec 30 rug . 2017-08-30 19:03 '17 19:03 2017-08-30 19:03

Šį klausimą sprendžiau taip.

Naudodamas „api“ pranešimą, aš siunčiau sveikųjų skaičių sąrašą kaip duomenis.

Tada aš grąžinau duomenis kaip ienumerable.

Siuntimo kodas atrodo taip:

 public override IEnumerable<Contact> Fill(IEnumerable<int> ids) { IEnumerable<Contact> result = null; if (ids!=null { try { using (var client = new HttpClient()) { client.BaseAddress = new Uri("http://localhost:49520/"); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); String _endPoint = "api/" + typeof(Contact).Name + "/ListArray"; HttpResponseMessage response = client.PostAsJsonAsync<IEnumerable<int>>(_endPoint, ids).Result; response.EnsureSuccessStatusCode(); if (response.IsSuccessStatusCode) { result = JsonConvert.DeserializeObject<IEnumerable<Contact>>(response.Content.ReadAsStringAsync().Result); } } } catch (Exception) { } } return result; } 

Priėmimo kodas yra toks:

 // POST api/<controller> [HttpPost] [ActionName("ListArray")] public IEnumerable<Contact> Post([FromBody]IEnumerable<int> ids) { IEnumerable<Contact> result = null; if (ids != null  ids.Count() > 0) { return contactRepository.Fill(ids); } return result; } 

Jis puikiai tinka vienam įrašui ar daugeliui įrašų. Pripildymas yra perkrautas metodas naudojant „DapperExtensions“:

 public override IEnumerable<Contact> Fill(IEnumerable<int> ids) { IEnumerable<Contact> result = null; if (ids != null  ids.Count() > 0) { using (IDbConnection dbConnection = ConnectionProvider.OpenConnection()) { dbConnection.Open(); var predicate = Predicates.Field<Contact>(f => f.id, Operator.Eq, ids); result = dbConnection.GetList<Contact>(predicate); dbConnection.Close(); } } return result; } 

Tai leidžia ištraukti duomenis iš sudėtinės lentelės (identifikatorių sąrašo), o tada grąžinti įrašus, kuriuos tikrai domina tikslinė lentelė.

Tą patį galite padaryti su pristatymu, tačiau tai suteikia jums šiek tiek daugiau kontrolės ir lankstumo.

Be to, informacija apie tai, ko ieškote iš duomenų bazės, užklausos eilutėje nerodoma. Taip pat nereikia konvertuoti CSV failų.

Turite prisiminti, kad naudojant bet kokį įrankį, pvz., Interneto api 2.x sąsają, gaukite, įdėkite, skelbkite, ištrinkite, galvos ir tt funkcijas. turi bendro naudojimo, bet neapsiriboja šiuo naudojimu.

Taigi, nors laiškai paprastai naudojami kuriant interneto api sąsajoje, tai neapsiriboja šiuo naudojimu. Tai yra įprastas html skambutis, kuris gali būti naudojamas bet kokiems html praktikos leidžiamiems tikslams.

Be to, išsami informacija apie tai, kas vyksta, yra paslėpta nuo tų „smalsių akių“, apie kurias mes girdime tiek daug šių dienų.

Lankstumas įvardijant konvencijas interneto api 2.x sąsajoje ir naudojant įprastą interneto skambutį reiškia, kad siunčiate žiniatinklio avi skambutį, kuris klaidina snooperius, manydamas, kad jūs tikrai darote kažką kito. Pavyzdžiui, galite naudoti „POST“, kad gautumėte duomenis.

1
27 окт. atsakymas, kurį pateikė Timothy Dooling, spalio 27 d 2015-10-27 16:45 '15, 4:45 pm 2015-10-27 16:45

Aš iš pradžių naudoju sprendimą, kurį @tMrchief jau daugelį metų veikia (jis veikia gerai). Bet kai aš pridėjau „ Swagger“ į API dokumentacijos projektą, mano galutinis taškas NE parodytas.

Tai užtruko šiek tiek laiko, bet tai buvo, ką aš atėjau. Jis veikia su „Swagger“, o API API parašai atrodo švaresni:

Galų gale galite padaryti:

  // GET: /api/values/1,2,3,4 [Route("api/values/{ids}")] public IHttpActionResult GetIds(int[] ids) { return Ok(ids); } 

WebApiConfig.cs

 public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Allow WebApi to Use a Custom Parameter Binding config.ParameterBindingRules.Add(descriptor => descriptor.ParameterType == typeof(int[])  descriptor.ActionDescriptor.SupportedHttpMethods.Contains(HttpMethod.Get) ? new CommaDelimitedArrayParameterBinder(descriptor) : null); // Allow ApiExplorer to understand this type (Swagger uses ApiExplorer under the hood) TypeDescriptor.AddAttributes(typeof(int[]), new TypeConverterAttribute(typeof(StringToIntArrayConverter))); // Any existing Code .. } } 

Sukurti naują klasę: CommaDelimitedArrayParameterBinder.cs

 public class CommaDelimitedArrayParameterBinder : HttpParameterBinding, IValueProviderParameterBinding { public CommaDelimitedArrayParameterBinder(HttpParameterDescriptor desc) : base(desc) { } /// <summary> /// Handles Binding (Converts a comma delimited string into an array of integers) /// </summary> public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { var queryString = actionContext.ControllerContext.RouteData.Values[Descriptor.ParameterName] as string; var ints = queryString?.Split(',').Select(int.Parse).ToArray(); SetValue(actionContext, ints); return Task.CompletedTask; } public IEnumerable<ValueProviderFactory> ValueProviderFactories { get; } = new[] { new QueryStringValueProviderFactory() }; } 

Sukurti naują klasę: StringToIntArrayConverter.cs

 public class StringToIntArrayConverter : TypeConverter { public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); } } 

Pastabos:

0
29 марта '18 в 22:48 2018-03-29 22:48 atsakymas yra suteiktas crabCRUSHERclamCOLLECTOR kovo 29, 18, 22:48 2018-03-29 22:48

Užuot naudoję pasirinktinį ModelBinder, galite naudoti pasirinktinį tipą su TypeConverter.

 [TypeConverter(typeof(StrListConverter))] public class StrList : List<string> { public StrList(IEnumerable<string> collection) : base(collection) {} } public class StrListConverter : TypeConverter { public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value == null) return null; if (value is string s) { if (string.IsNullOrEmpty(s)) return null; return new StrList(s.Split(',')); } return base.ConvertFrom(context, culture, value); } } 

Privalumas yra tai, kad jis labai supaprastina Web API metodo parametrus. Net nereikia nurodyti [FromUri].

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

Šis pavyzdys skirtas styginių sąrašui, tačiau galite padaryti categoryIds.Select(int.Parse) arba tiesiog rašyti „IntList“.

0
05 февр. Atsakymą pateikė PhillipM 05 Feb. 2018-02-05 14:26 '18, 14:26 pm 2018-02-05 14:26

„ASP.NET Core 2.0“ sprendimas (paruoštas „Swagger“)

Įvestis

 DELETE /api/items/1,2 DELETE /api/items/1 

kodą

Užrašykite tiekėją (kaip MVC žino, ką naudoti rišiklį)

 public class CustomBinderProvider : IModelBinderProvider { public IModelBinder GetBinder(ModelBinderProviderContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (context.Metadata.ModelType == typeof(int[]) || context.Metadata.ModelType == typeof(List<int>)) { return new BinderTypeModelBinder(typeof(CommaDelimitedArrayParameterBinder)); } return null; } } 

Parašykite faktinį klijų priedą (pasiekite visą informaciją apie užklausą, veiksmą, modelius, tipus ir tt)

 public class CommaDelimitedArrayParameterBinder : IModelBinder { public Task BindModelAsync(ModelBindingContext bindingContext) { var value = bindingContext.ActionContext.RouteData.Values[bindingContext.FieldName] as string; // Check if the argument value is null or empty if (string.IsNullOrEmpty(value)) { return Task.CompletedTask; } var ints = value?.Split(',').Select(int.Parse).ToArray(); bindingContext.Result = ModelBindingResult.Success(ints); if(bindingContext.ModelType == typeof(List<int>)) { bindingContext.Result = ModelBindingResult.Success(ints.ToList()); } return Task.CompletedTask; } } 

Užregistruokite jį su MVC

 services.AddMvc(options => { // add custom binder to beginning of collection options.ModelBinderProviders.Insert(0, new CustomBinderProvider()); }); 

Naudokite pavyzdį su gerai dokumentuotu „Swagger“ valdikliu

 /// <summary> /// Deletes a list of items. /// </summary> /// <param name="itemIds">The list of unique identifiers for the items.</param> /// <returns>The deleted item.</returns> /// <response code="201">The item was successfully deleted.</response> /// <response code="400">The item is invalid.</response> [HttpDelete("{itemIds}", Name = ItemControllerRoute.DeleteItems)] [ProducesResponseType(typeof(void), StatusCodes.Status204NoContent)] [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] public async Task Delete(List<int> itemIds) => await _itemAppService.RemoveRangeAsync(itemIds); 
0
05 апр. Atsakymą pateikė Victorio Berra 05 balandžio. 2018-04-05 22:38 '18, 22:38 pm 2018-04-05 22:38

Kiti klausimai apie žymių arba Užduoti klausimą