【问题标题】:DataSourceRequest is not deserializing for a WebAPI Get methodDataSourceRequest 没有为 WebAPI Get 方法反序列化
【发布时间】:2018-07-04 00:19:59
【问题描述】:

我正在尝试像这样从 Angular 5 调用 WebAPI 方法:

selectClaims(state: DataSourceRequestState):Observable<DataResult>
{
    return this.http.get<GridDataResult>(`${this.apiUrl}/SelectClaims?${toDataSourceRequestString(state)}`);
}

按预期调用 API 方法。 API方法是:

    [Route("SelectClaims")]
    [HttpGet]
    public IHttpActionResult SelectClaims([FromUri][DataSourceRequest]DataSourceRequest ClaimsRequest)
        {
        if(ClaimsRequest == null)
            ClaimsRequest=new DataSourceRequest { Page=1, PageSize=20 };
        var result = _db.Claims.ToDataSourceResult(ClaimsRequest, c => { c.SortHistory(); return c; });
        return Ok(result);
        }

问题在于 ClaimsRequest 只能正确反序列化 Page 和 PageSize。过滤器和排序不通过:

Fiddler 告诉我来自 Angular 的 URL 是: GET /api/v1/Claims/SelectClaims?filter=id~eq~2&amp;page=1&amp;sort=firstName-asc&amp;pageSize=20 HTTP/1.1,但在控制器中 filter 和 sort 都为空。

如果我通过 Swagger 创建一个 URL,例如:'http://localhost:50223/api/v1/Claims/SelectClaims?ClaimsRequest.page=1&ClaimsRequest.pageSize=11&ClaimsRequest.sorts=firstName-desc',我确实在 API 方法中看到了一个排序数组,但“成员”字段为空。

任何尝试通过 Swagger 添加过滤器(如“http://localhost:50223/api/v1/Claims/SelectClaims?ClaimsRequest.page=1&ClaimsRequest.pageSize=11&ClaimsRequest.filters=id~eq~2”)都会导致“无法创建接口实例”。错误。

状态是来自 Angular 的 Kendo Grid 的 angular 组件中的 DataSourceRequestState

我在一个简单的测试程序中对此进行了模拟,并且一切正常。我的测试程序的唯一区别是 API 控制器面向 .Net Core,而实际系统面向 .Net 4.6.1。

出于某种原因,我是否必须在 .Net 4.6.1 中手动反序列化,还是这里发生了其他事情?

【问题讨论】:

  • 你解决过这个问题吗?我有同样的问题
  • 已经有一段时间了,但我认为答案是该方法不应该有 [HttpGet] 因为 Telerik 正在使用 Post 方法来请求(即使它看起来应该是一个 Get) .请让我知道这是否适合您。
  • 嗨,John,是的,我在运行 MVC 版本后发现了同样的事情,并看到将“aspmvc-api”添加到类型将调用从 GET 切换到 POST。糟糕的文档。我最终制作了一个新对象,其参数与 [FromUri] 的 DataSourceRequest 参数相同,并且效果很好(需要它在 GET 上运行)。我不得不再次映射过滤器和排序,但无论如何我都必须触摸它们,因为我的 VM 属性与实体不匹配,因此搜索会失败。谢谢你回来!

标签: asp.net-web-api kendo-grid angular5


【解决方案1】:

它应该是 POST 而不是 GET。像这样的:

return this.http.post<GridDataResult>(`${this.apiUrl}/SelectClaims`, toDataSourceRequestString(state)});

我需要它是一个 GET (URL),所以我创建了一个新对象

public class GridParamaterBinder
{
    public int Page { get; set; }
    public int PageSize { get; set; }
    public string Filter { get; set; }
    public string Sort { get; set; }

    public DataSourceRequest ToDataSourceRequest(IConfigurationProvider mapper, Func<string, string> OverDefaultParamaterMapping)
    {
        DataSourceRequest result = new DataSourceRequest();

        result.Page = Page;
        result.PageSize = PageSize;
        result.Sorts = GridDescriptorSerializer.Deserialize<SortDescriptor>(Sort);
        result.Filters = FilterDescriptorFactory.Create(Filter);

        return result;
    }
}

并用它代替 Telerik 的努力。

在 API 中我像这样绑定它

public virtual DataSourceResult Get([FromUri]GridParamaterBinder request)

然后像这样使用它

DataSourceResult results = query.ToDataSourceResult(request.ToDataSourceRequest(),  r => (r)));

【讨论】:

    【解决方案2】:

    感谢@KevDevMan 的解决方案。我找到了这个example, 然后我像这样更改了我的 API 控制器,它就像一个魅力:

    [HttpGet, Route("for-kendo-grid")]
    public DataSourceResult GetProducts([System.Web.Http.ModelBinding.ModelBinder(typeof(WebApiDataSourceRequestModelBinder))] DataSourceRequest request)
    

    解释here

    【讨论】:

      猜你喜欢
      • 2013-09-21
      • 2020-07-11
      • 1970-01-01
      • 2016-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多