如何绑定 Kendo.MVC DataSource Read in WebApi using Ajax Request on Razor page
How to bind Kendo.MVC DataSource Read in WebApi using Ajax Request on Razor page
我有一个定义如下的网格
@(Html.Kendo().Grid<DtoStuff>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(c => c.Number);
columns.Bound(c => c.Date);
columns.Bound(c => c.Total);
})
.Reorderable(reorderable => reorderable.Columns(true))
.Resizable(resizable => resizable.Columns(true))
.Pageable()
.Filterable(f => f.Extra(false).Mode(GridFilterMode.Menu))
.Sortable(sorting => sorting.SortMode(GridSortMode.SingleColumn).AllowUnsort(false))
.ColumnMenu()
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(true)
.PageSize(15)
.Model(model => model.Id(p => p.Number))
.Read(read => read
.Url("https://local-api.net/Customer/v1/Stuff/Stuffs")
)
.Sort(s => s.Add("Date").Descending())
.Filter(f => f.Add(a => a.Date).IsGreaterThanOrEqualTo(DateTime.Now.AddYears(-1)))
)
)
我想添加一个自定义授权令牌,主要是:http://www.telerik.com/forums/cannot-add-a-custom-http-header
但是当我这样做时,发送的参数都搞砸了,我不知道如何正确解析它们。
这是将 Header 添加到数据源
的脚本
<script>
$(function () {
var grid = $("#grid").data("kendoGrid");
grid.dataSource.transport.options.read.beforeSend = function (xhr) {
xhr.setRequestHeader('Authorization', 'Bearer @Session["Authorization"]');
};
grid.dataSource.read();
});
</script>
这里是 WebApi 中的控制器
Controller.cs
[HttpPost, Route("Stuffs")]
public IHttpActionResult PostStuffs([DataSourceRequest] DataSourceRequest request)
{
if (ModelState.IsValid)
{
using (var entities = dboModel.Value)
{
var query = entities.Stuff
.ProjectToType<DtoStuff>();
request = request == null ? new DataSourceRequest() : request;
var result = query.ToDataSourceResult(request);
return Ok(result);
}
}
else
{
return BadRequest("Request is not Valid");
}
}
概览
客户端 (CSHTML)
- 确保数据源读取操作不会自动绑定
- 将数据源设置为 Ajax
- 将 ServerOperation 设置为 true
- 使用 Type = GET 设置读取操作(重要)
应该看起来像:
@(Html.Kendo().Grid<DtoStuff>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(c => c.Number);
columns.Bound(c => c.Date)
columns.Bound(c => c.Total);
})
.Reorderable(reorderable => reorderable.Columns(true))
.Resizable(resizable => resizable.Columns(true))
.Pageable()
.Filterable(f => f.Extra(false).Mode(GridFilterMode.Menu))
.ColumnMenu()
.AutoBind(false)
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(true)
.PageSize(15)
.Model(model => model.Id(p => p.Number))
.Read(read => read
.Url("https://local-api.net/Customer/v1/Stuff/Stuffs")
.Type(HttpVerbs.Get)
)
.Sort(s => s.Add("Date").Descending())
.Filter(f => f.Add(a => a.Date).IsGreaterThanOrEqualTo(DateTime.Now.AddYears(-1)))
)
)
客户端(脚本)
添加 beforeSend 匿名函数,如下所示:http://www.telerik.com/forums/cannot-add-a-custom-http-header
$(function () {
var grid = $("#grid").data("kendoGrid");
grid.dataSource.transport.options.read.beforeSend = function (xhr) {
xhr.setRequestHeader('Authorization', 'Bearer @Session["Authorization"]');
if('@Session["StuffedHeader"]' != '')
{
xhr.setRequestHeader('StuffedHeader', '@Session["StuffedHeader"]');
}
};
grid.dataSource.read();
});
服务器端(Controller.cs)
- 创建选项请求(CORS 需要)
- 使用这个作为请求参数实现get请求:
[ModelBinder(typeof(WebApiDataSourceRequestModelBinder))]
DataSourceRequest request
- 选择添加的位置'Access-Control-Allow-Origin'
- 使用 [EnableCors("", "","*")]
使用response.Headers.Add("Access-Control-Allow-Origin","*");在 OptionMethod
[RoutePrefix("FluffyThings/v1/Stuff")]
[EnableCors("*", "*","*")]
public class StuffController : ApiController
{
[HttpGet, Route("Stuffs")]
public IHttpActionResult Get([ModelBinder(typeof(WebApiDataSourceRequestModelBinder))] DataSourceRequest request)
{
return PostStuffs(request);
}
[HttpPost, Route("Stuffs")]
public IHttpActionResult PostStuffs([DataSourceRequest] DataSourceRequest request)
{
if (ModelState.IsValid)
{
using (var entities = dboModel.Value)
{
var query = entities.stuff.ProjectToType<DtoStuff>();
request = request == null ? new DataSourceRequest() : request;
var result = query.ToDataSourceResult(request);
return Ok(result);
}
}
else
{
return BadRequest("Request is not Valid");
}
}
[HttpOptions, Route("Stuffs")]
public HttpResponseMessage OptionsStuffs()
{
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);
//Use this to allow specific origin to access content
//response.Headers.Add("Access-Control-Allow-Origin", "*");
response.Headers.Add("Access-Control-Allow-Methods", "POST, GET");
response.Headers.Add("Access-Control-Max-Age", "3600");
response.Headers.Add("Access-Control-Allow-Headers", "Authorization, StuffHeader");
return response;
}
}
我有一个定义如下的网格
@(Html.Kendo().Grid<DtoStuff>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(c => c.Number);
columns.Bound(c => c.Date);
columns.Bound(c => c.Total);
})
.Reorderable(reorderable => reorderable.Columns(true))
.Resizable(resizable => resizable.Columns(true))
.Pageable()
.Filterable(f => f.Extra(false).Mode(GridFilterMode.Menu))
.Sortable(sorting => sorting.SortMode(GridSortMode.SingleColumn).AllowUnsort(false))
.ColumnMenu()
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(true)
.PageSize(15)
.Model(model => model.Id(p => p.Number))
.Read(read => read
.Url("https://local-api.net/Customer/v1/Stuff/Stuffs")
)
.Sort(s => s.Add("Date").Descending())
.Filter(f => f.Add(a => a.Date).IsGreaterThanOrEqualTo(DateTime.Now.AddYears(-1)))
)
)
我想添加一个自定义授权令牌,主要是:http://www.telerik.com/forums/cannot-add-a-custom-http-header
但是当我这样做时,发送的参数都搞砸了,我不知道如何正确解析它们。
这是将 Header 添加到数据源
的脚本<script>
$(function () {
var grid = $("#grid").data("kendoGrid");
grid.dataSource.transport.options.read.beforeSend = function (xhr) {
xhr.setRequestHeader('Authorization', 'Bearer @Session["Authorization"]');
};
grid.dataSource.read();
});
</script>
这里是 WebApi 中的控制器 Controller.cs
[HttpPost, Route("Stuffs")]
public IHttpActionResult PostStuffs([DataSourceRequest] DataSourceRequest request)
{
if (ModelState.IsValid)
{
using (var entities = dboModel.Value)
{
var query = entities.Stuff
.ProjectToType<DtoStuff>();
request = request == null ? new DataSourceRequest() : request;
var result = query.ToDataSourceResult(request);
return Ok(result);
}
}
else
{
return BadRequest("Request is not Valid");
}
}
概览
客户端 (CSHTML)
- 确保数据源读取操作不会自动绑定
- 将数据源设置为 Ajax
- 将 ServerOperation 设置为 true
- 使用 Type = GET 设置读取操作(重要)
应该看起来像:
@(Html.Kendo().Grid<DtoStuff>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(c => c.Number);
columns.Bound(c => c.Date)
columns.Bound(c => c.Total);
})
.Reorderable(reorderable => reorderable.Columns(true))
.Resizable(resizable => resizable.Columns(true))
.Pageable()
.Filterable(f => f.Extra(false).Mode(GridFilterMode.Menu))
.ColumnMenu()
.AutoBind(false)
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(true)
.PageSize(15)
.Model(model => model.Id(p => p.Number))
.Read(read => read
.Url("https://local-api.net/Customer/v1/Stuff/Stuffs")
.Type(HttpVerbs.Get)
)
.Sort(s => s.Add("Date").Descending())
.Filter(f => f.Add(a => a.Date).IsGreaterThanOrEqualTo(DateTime.Now.AddYears(-1)))
)
)
客户端(脚本)
添加 beforeSend 匿名函数,如下所示:http://www.telerik.com/forums/cannot-add-a-custom-http-header
$(function () { var grid = $("#grid").data("kendoGrid"); grid.dataSource.transport.options.read.beforeSend = function (xhr) { xhr.setRequestHeader('Authorization', 'Bearer @Session["Authorization"]'); if('@Session["StuffedHeader"]' != '') { xhr.setRequestHeader('StuffedHeader', '@Session["StuffedHeader"]'); } }; grid.dataSource.read(); });
服务器端(Controller.cs)
- 创建选项请求(CORS 需要)
- 使用这个作为请求参数实现get请求:
[ModelBinder(typeof(WebApiDataSourceRequestModelBinder))] DataSourceRequest request
- 选择添加的位置'Access-Control-Allow-Origin'
- 使用 [EnableCors("", "","*")]
使用response.Headers.Add("Access-Control-Allow-Origin","*");在 OptionMethod
[RoutePrefix("FluffyThings/v1/Stuff")] [EnableCors("*", "*","*")] public class StuffController : ApiController { [HttpGet, Route("Stuffs")] public IHttpActionResult Get([ModelBinder(typeof(WebApiDataSourceRequestModelBinder))] DataSourceRequest request) { return PostStuffs(request); } [HttpPost, Route("Stuffs")] public IHttpActionResult PostStuffs([DataSourceRequest] DataSourceRequest request) { if (ModelState.IsValid) { using (var entities = dboModel.Value) { var query = entities.stuff.ProjectToType<DtoStuff>(); request = request == null ? new DataSourceRequest() : request; var result = query.ToDataSourceResult(request); return Ok(result); } } else { return BadRequest("Request is not Valid"); } } [HttpOptions, Route("Stuffs")] public HttpResponseMessage OptionsStuffs() { HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK); //Use this to allow specific origin to access content //response.Headers.Add("Access-Control-Allow-Origin", "*"); response.Headers.Add("Access-Control-Allow-Methods", "POST, GET"); response.Headers.Add("Access-Control-Max-Age", "3600"); response.Headers.Add("Access-Control-Allow-Headers", "Authorization, StuffHeader"); return response; } }