отправка массива объектов в функцию get - PullRequest
1 голос
/ 06 июня 2019

Я использую .NET Core и WebApi и пытаюсь выяснить, как будет выглядеть URL для отправки массива объектов через.

Например

public class DataObject
{
  public int id { get; set;}
  public string name { get; set }
}

[HttpGet()]
public <ActionResult<string>> GetSomething(DataObject[] data))
{
  //do something and return a string
}

как будет выглядеть URL, чтобы сделать это?Должен ли я использовать FromQuery или FromRoute на данных?На HttpGet (), что должно быть в скобках?"{data}" или что-то еще?

Все, что я могу найти до сих пор, было в целочисленных или строковых массивах, но не в сложных массивах для вызова get.

Update

Все еще не могу заставить это работать, хотя я уверен, что полученный ответ должен работать.Вот еще немного кода.

[Route("api/[controller]/[action]")]

 [HttpGet()]
    [ProducesResponseType((int)HttpStatusCode.BadRequest)]
    [ProducesResponseType(typeof(GridResult), (int)HttpStatusCode.OK)]
    public async Task<ActionResult<GridResult>> GetGridData<TFilter1, TFilter2, TItem1>
        ([FromQuery]string sessionID, [FromQuery] GridDetails details, [FromQuery] TFilter1[] TFilters1, [FromQuery] TFilter2[] TFilters2, [FromQuery] TItem1[] TSorts)

и, наконец, сгенерированный мной URL, который выдает 404.

https://localhost:44366/api/grid/GetGridData/sessionID=598357390&details?NUMBER_OF_ROWS_FIRST_RETURNED=100&CURSOR_POSITION=0&RESULT_IN_SAXORDER=false&TERSERESPONSE=true&IsStaticList=true&GRID_TYPE=list&REQUEST_TYPE=LIST.DATA_ONLY.STORED&GRID_NAME=WUWP09&TFilters1[0].AliasName=PRO_CODE&TFilters1[0].Operator=%3D&TFilters1[0].SEQNUM=1&TFilters1[1].AliasName=APR_CLASS&TFilters1[1].Operator=%3D&Tsorts[1].SEQNUM=2&Tsorts[0].ALIAS_NAME=pvd_value&Tsorts[0].TYPE=ASC

Обновление 2

https://localhost:44366/api/grid/GetGridData?sessionID=598357390&details.NUMBER_OF_ROWS_FIRST_RETURNED=100&details.CURSOR_POSITION=0&details.RESULT_IN_SAXORDER=false&details.TERSERESPONSE=true&details.IsStaticList=true&details.GRID_TYPE=list&details.REQUEST_TYPE=LIST.DATA_ONLY.STORED&details.GRID_NAME=WUWP09&details.TAB_NAME&details.LOCALIZE_RESULT&details.USER_FUNCTION_NAME&details.TOTALRECORDS&details.RES_IsMoreRecords&details.RES_CURRENT_CURSOR_POSITION&TFilters1[0].AliasName=PRO_CODE&TFilters1[0].Operator=%3D&TFilters1[0].SEQNUM=1&TFilters1[1].AliasName=APR_CLASS&TFilters1[1].Operator=%3D&Tsorts[1].SEQNUM=2&Tsorts[0].ALIAS_NAME=pvd_value&Tsorts[0].TYPE=ASC

Обновление 3

Startup.cs открытый класс Startup {public Startup (конфигурация IConfiguration) {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().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        var _accessor = services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        var config = new GridServices.Models.config();
        Configuration.Bind("Connections", config);
        services.AddSingleton(config);
        services.AddSingleton(new Controllers.GridController(config));
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }
        app.UseHttpsRedirection();
        app.UseMvc();
    }
}

GridController

namespace EAMWebApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class GridController : ControllerBase
{
    config Config { get; }
    //private readonly LinkGenerator _linkGenerator;

    public GridController(config config)
    {
        config = Config;
        //_linkGenerator = linkGenerator;
    }

    [HttpGet()]
    [ProducesResponseType((int)HttpStatusCode.BadRequest)]
    [ProducesResponseType(typeof(GridResult), (int)HttpStatusCode.OK)]
    public async Task<ActionResult<GridResult>> GetGridData<TFilter1, TFilter2, TItem1>
        ([FromQuery]string sessionID, [FromQuery] GridDetails details, [FromQuery] TFilter1[] TFilters1 = null, [FromQuery] TFilter2[] TFilters2 = null, [FromQuery] TItem1[] TSorts = null)
    {//Do something}
}

GridDetails

namespace GridServices.Models
{
    public class GridDetails
    {
        public string GRID_NAME { get; set; }
        public string NUMBER_OF_ROWS_FIRST_RETURNED { get; set; }        
        public string CURSOR_POSITION { get; set; }        
        public string TAB_NAME { get; set; }        
        public string RESULT_IN_SAXORDER { get; set; }        
        public string TERSERESPONSE { get; set; }        
        public string LOCALIZE_RESULT { get; set; }        
        public string USER_FUNCTION_NAME { get; set; }        
        public string TOTALRECORDS { get; set; }        
        public bool RES_IsMoreRecords { get; set; }        
        public bool IsStaticList { get; set; }        
        public string GRID_TYPE { get; set; }        
        public string REQUEST_TYPE { get; set; }        
        public string RES_CURRENT_CURSOR_POSITION { get; set; }
    }
}

MultiAddOnFilter

public class MultiAddOnFilter
{        
    public string ALIAS_NAME { get; set; }
    public string OPERATOR { get; set; }
    public string OPERATORSpecified { get; set; }
    public string VALUE { get; set; }
    public string LPAREN { get; set; }
    public string RPAREN { get; set; }        
    public string JOINER { get; set; }        
    public string JOINERSpecified { get; set; }        
    public string SEQNUM { get; set; }

    public MultiAddOnFilter(string _ALIAS_NAME, string _OPERATOR, string _VALUE)
    {
        ALIAS_NAME = _ALIAS_NAME;
        OPERATOR = _OPERATOR;
        OPERATORSpecified = "true";
        VALUE = _VALUE;
    }
}

Сортировка пространства имен GridServices.Models {public class Sort {открытая строка ALIAS_NAME {get;задавать;} публичная строка TYPE {get;задавать;} открытая строка TYPESpecified {get;задавать;}

    public Sort(string _ALIAS_NAME, string _TYPE)
    {
        ALIAS_NAME = _ALIAS_NAME;
        TYPE = _TYPE;
        TYPESpecified = "true";
    }
}

}

1 Ответ

1 голос
/ 07 июня 2019

как будет выглядеть URL для этого?

Это должно быть примерно так:

GET /Somecontroller/GetSomething?data[0].id=1&data[0].name=nameA&data[1].id=2&data[1].name=nameB&data[2].id=3&data[2].name=nameC

Эта полезная нагрузка почти такая же, как вы публикуете в формате application/x-www-form-urlencoded, за исключением того, что вы отправите ее в виде строки запроса.


[Изменить]

Если бы один из этих элементов был пустым, должен ли я передать ему% 00, чтобы указать нулевое значение?

  1. Давайтескажем, у вас есть такой массив объектов:
data = [
  {
    "id": 1,
    "name": "nameA"
  },
  {
    "id": 2,
    "name": null            
  },
  {
    "id": 3,
    "name": "nameC"
  }
]

Обратите внимание на data[1].name==null.вам не нужно указывать data[1].name:

?data[0].id=1&data[0].name=nameA&data[1].id=2&data[2].id=3&data[2].name=nameC
Если весь элемент data[1] равен null, просто настройте индекс от data[2] до data[1]:
data[0].id=1&data[0].name=nameA&data[1].id=3&data[1].name=name

Или вы можете добавить пустое поле для этого элемента:

?data[0].id=1&data[0].name=nameA&data[1].id=&data[2].id=3&data[2].name=nameC

Что, если весь DataObject был бы нулевым?/ GetSomething? Data =% 00?

вам не нужно указывать /GetSomething?data=%00, просто отправьте запрос на /GetSomething?, и тогда вы получите пустой массив.


[Edit2]

Есть две причины, которые всегда направляют вас к результату 404:

  1. Вырегистрация вашего GridController как singleton .MVC автоматически зарегистрирует контроллеры (как услуга scoped ).Просто удалите эту строку:
<strike>services.AddSingleton(new Controllers.GridController(config));</strike>
Ваше действие контроллера GetGridData<TFilter1, TFilter2, TItem1> является универсальным методом.Это не будет работать по умолчанию.На SO уже обсуждается тема .Я бы также предложил вам использовать определенный тип GridFilter для каждого метода.Если вы обнаружите, что повторяете ту же логику, вы можете поместить свой универсальный метод в родительский класс MySupperGridBaseController<TFilter1, TFilter2, TItem1>, как показано ниже:
public class MySupperGridBaseController<TFilter1, TFilter2, TItem1> : ControllerBase
{
    public async Task<ActionResult<GridResult>> GetGridData
            ([FromQuery]string sessionID, [FromQuery] GridDetails details, [FromQuery] TFilter1[] TFilters1 = null, [FromQuery] TFilter2[] TFilters2 = null, [FromQuery] TItem1[] TSorts = null)
    {
         ...
    }
}


// now we could reuse the same logic inherited from parent 
public class GridController : MySupperGridBaseController<MultiAddOnFilter, MultiAddOnFilter, Sort>
{

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...