How to set over 29 parameters in an Http GET request

I am trying to write a method in my Controller class that responds to an Http GET request. The application is an ASP.NET Core 2.0 API.

The method is as follows:

[HttpGet("GetObjects/{parameter1?}/{parameter2:decimal?}.../{parameter29:bool?}"]
public IActionResult(List<string> parameter1 = null, decimal? parameter2 = null, ..., bool? parameter29 = null) 
{

}

When I go to add the 30th parameter, I get this exception: OverflowException: the value was too large or too small for the decimal number. Additional information in the image.

I tried to add as a parameter a null string list, a null bool value, and a null value. They all work great when changing the parameter of an existing method.

I see this error as soon as I create my project, and do not start / use it. The only change I make between the working version and the failed one is to add / {parameter29: bool?} (Or any other type of parameter) to the end of the HttpGet attribute route.

enter image description here

I am trying to get all database records that are related to this object. I check which parameters are not null and filter the list of entries accordingly. Then I return the filtered list.

+4
source share
3 answers

This is really a bug in asp.net kernel routing. Looking at RoutePrecedence.cs , we see:

// Compute the precedence for generating a url
// e.g.: /api/template          == 5.5
//       /api/template/{id}     == 5.53
//       /api/{id:int}          == 5.4
//       /api/template/{id:int} == 5.54
public static decimal ComputeOutbound(RouteTemplate template)
{
    // Each precedence digit corresponds to one decimal place. For example, 3 segments with precedences 2, 1,
    // and 4 results in a combined precedence of 2.14 (decimal).
    var precedence = 0m;

    for (var i = 0; i < template.Segments.Count; i++)
    {
        var segment = template.Segments[i];

        var digit = ComputeOutboundPrecedenceDigit(segment);
        Debug.Assert(digit >= 0 && digit < 10);

        precedence += decimal.Divide(digit, (decimal)Math.Pow(10, i));
    }

    return precedence;
}

, , . , /api/template/{id} /api/template, , .

, , , , :

for (var i = 0; i < template.Segments.Count; i++) {
     ... (decimal)Math.Pow(10, i);
}

, Math.Pow(10, segmentIndex) decimal. decimal Math.Pow(10, 28) Math.Pow(10, 29). , 30 - .

gitub asp.net core, , , , 30 .

. json model POSTed .

+7

, , , -, 30 ( , ), . , . , , , ( 30 ).

+4

UPDATE


( , , , , ).

@axelrotter.

:

  • Visual Studio ( 2014 15.4.1)
  • , ,
  • - ASP.NET
  • -
  • ValuesController.cs
  • (NB: 28 , , ):

    [HttpGet("{a}/{b}/{c}/{d}/{e}/{f}/{g}/{h}/{i}/{j}/{k}/{l}/{m}/{n}/{o}/{p}/{q}/{r}/{s}/{t}/{u}/{v}/{w}/{x}/{y}/{z}/{a2}/{b2}")]
    public string Get(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, int n, int o, int p, int q, int r, int s, int t, int u, int v, int w, int x, int y, int z, int a2, int b2) =>
        $"Hello {a} {b} ...";
    
  • ;

  • ; .

ASP.NET Core GitHub , . , (, , , , - , , ).


ValuesController.cs

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;

namespace WebApplication3.Controllers
{
    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        // GET api/values
        [HttpGet]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }


        [HttpGet("{a}/{b}/{c}/{d}/{e}/{f}/{g}/{h}/{i}/{j}/{k}/{l}/{m}/{n}/{o}/{p}/{q}/{r}/{s}/{t}/{u}/{v}/{w}/{x}/{y}/{z}/{a2}/{b2}")]
        public string Get(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, int n, int o, int p, int q, int r, int s, int t, int u, int v, int w, int x, int y, int z, int a2, int b2) =>
            $"Hello {a} {b} ...";


    }
}

appsettings.json

{
  "Logging": {
    "IncludeScopes": false,
    "Debug": {
      "LogLevel": {
        "Default": "Warning"
      }
    },
    "Console": {
      "LogLevel": {
        "Default": "Warning"
      }
    }
  }
}

Program.cs

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;

namespace WebApplication3
{
    public class Program
    {
        public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
    }
}

Startup.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace WebApplication3
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseDeveloperExceptionPage();
            app.UseMvc();
        }
    }
}
+2

Source: https://habr.com/ru/post/1695334/


All Articles