发送对象数组到get函数

时间:2019-06-06 18:22:37

标签: asp.net-core-webapi

我正在使用.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
}

该网址将如何执行此操作?我应该在数据上使用FromQuery或FromRoute吗?在HttpGet()上,括号中应该是什么? “ {data}”还是其他?

到目前为止,我所能找到的所有东西都在整数数组或字符串数​​组上,但不是get调用的复杂数组。

更新

即使我确定收到的回复仍然有效,仍然无法使它正常工作。这是更多代码。

[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)

最后是我生成的网址,该网址抛出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      公共类创业     {         公共启动(IConfiguration配置)         {             配置=配置;         }

    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 {     公共课排序     {         公用字符串ALIAS_NAME {get;组; }         公用字符串TYPE {get;组; }         公共字符串TYPESpecified {组; }

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

}

1 个答案:

答案 0 :(得分:1)

  

该网址看起来像是什么?

应该类似于以下内容:

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
  1. 如果整个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注册为单个。 MVC将自动注册控制器(作为作用域服务)。只需删除该行:
services.AddSingleton(new Controllers.GridController(config));
  1. 您的GetGridData<TFilter1, TFilter2, TItem1>控制器操作是通用方法。默认情况下它将无法工作。已经有a thread on 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>
{

}