关于异步:是什么导致KendoUI Core应用程序中的ToDataSourceResult错误?

What is causing my ToDataSourceResult error in my KendoUI Core Application?

我已经使用WebAPI和KendoUI创建了一个.NET Core应用程序。我添加了一个通用存储库,当我尝试将数据源添加到Kendo Grid时,在消息中出现错误:

< Task< IEnumerable< Vessel>> does not contain a definition for
'ToDataSourceResult' and the best extension method overload
'QueryableExtensions.ToDataSourceResult(DataTable, DataSourceRequest)'
requires a receiver of type 'DataTable'

我遵循有关Core和WebApi的Kendo文档来完成此方法,但无法使其正常工作。我已经从项目中附加了与此错误和数据相关的代码。

Controllers / HomeController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;
using Microsoft.AspNetCore.Mvc;
using Senua.Interfaces;
using Senua.Models;
using System.Diagnostics;

namespace Senua.Controllers
{
    public class HomeController : Controller
    {
        private IVesselRepository service;

        public IActionResult Index()
        {
            return View();
        }
        [HttpGet]
        public DataSourceResult GetVessels([DataSourceRequest]DataSourceRequest request)
        {
            return service.GetAllVesselsAsync().ToDataSourceResult(request); <----Error appears here.
        }
        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }

    }
}

视图/首页/索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@(Html.Kendo().Grid<Senua.Models.Vessel>()
    .Name("vessel_grid")
    .Columns(columns =>
    {
        columns.Bound(p => p.Name);
    })
    .Pageable()
    .Filterable()
    .DataSource(dataSource =>
        dataSource
            .WebApi()
            .Events(events => events.Error("error_handler"))
            .Model(model =>
            {
                model.Id(p => p.Id);
            })
            .Read(read => read.Action("GetVessels","Home"))
          ))


    function error_handler(e) {
        var errors = $.parseJSON(e.xhr.responseText);
        if (errors) {
            alert("Errors:\
" + errors.join("\
"));
        }
    }

DAL /船只存储库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using Senua.Interfaces;
using Senua.Models;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Senua.DAL
{
    public class VesselRepository : Repository<Vessel>, IVesselRepository
    {
        public VesselRepository(LocalContext repositoryContext)
            : base(repositoryContext)
        {
        }
        public async Task<IEnumerable<Vessel>> GetAllVesselsAsync()
        {
            var vessel = await FindAllAsync();
            return vessel.OrderBy(x => x.Name);
        }
}

接口/ IVessel存储库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using Senua.Models;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Senua.Interfaces
{
    public interface IVesselRepository
    {
        Task<IEnumerable<Vessel>> GetAllVesselsAsync();
        Task<Vessel> GetVesselByIdAsync(int Id);
        Task CreateVesselAsync(Vessel vessel);
        Task UpdateVesselAsync(Vessel vessel);
        Task DeleteVesselAsync(Vessel vessel);
    }
}

DAL /存储库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using Senua.Interfaces;
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Senua.DAL
{
    public abstract class Repository< T > : IRepository< T > where T : class
    {
        protected LocalContext DbContext { get; set; }
        public Repository(LocalContext _context)
        {
            this.DbContext = _context;
        }
        public async Task<IEnumerable< T >> FindAllAsync()
        {
            return await this.DbContext.Set< T >().ToListAsync();
        }        
    }
}

接口/ IRepository

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Senua.Interfaces
{
    public interface IRepository< T >
    {
        Task<IEnumerable< T >> FindAllAsync();
        Task<IEnumerable< T >> FindByConditionAsync(Expression<Func<T, bool>> expression);
        void Create(T entity);
        void Update(T entity);
        void Delete(T entity);
        Task SaveAsync();
    }
}

在这方面我需要一些指导,我之前从未设置过异步存储库,所以它有点新,但是,从我所看到的情况来看,还可以,我已经与邮递员进行了测试。我注意到也有一个'ToDataSourceAsync',但是在尝试了之后也没有用。

TIA


这是我的Kendo MVC网格,需要异步功能。
这是一个复杂的情况,您需要使用异步DataSourceResult来绑定来自api的网格数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class HomeController : Controller
{
    private HttpClient _client = ApiHelper.Client;
    private Uri baseUri = ApiHelper._Client.BaseAddress;

    public ActionResult Index()
    {
        return View();
    }

    DataSourceResult result;
    JsonResult final;
    public async Task<ActionResult> GetList([DataSourceRequest] DataSourceRequest request)
    {
        int offset = 0;
        const int limit = 100;
        List<myModel> myModelList = new List<myModel>();
        using (var req = new HttpRequestMessage(HttpMethod.Get, baseUri + ConfigurationManager.AppSettings["V3BaseUri"] +"resource?offset=" + offset +"&limit=" + limit))
        using (var response = await ApiHelper.Client.SendAsync(req))
        {
             response.EnsureSuccessStatusCode();
                try
                {
                    var content = response.Content.ReadAsStringAsync().Result;
                    myModelList = JsonConvert.DeserializeObject<List<myModel>>(content);
                    result = await myModelList.ToDataSourceResultAsync(request);
                    final = Json(result);
                    return final;
                }
                catch (Exception exc)
                {
                    string message = exc.Message;
                    Console.WriteLine("Exception message: {0}", message);
                    throw;
                }
            }
        }

在我看来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@(Html.Kendo().Grid<Project.Models.myModel>()
            .Name("grid")
            .AutoBind(true)
            .Columns(columns =>
            {
                columns.Bound(c => c.Id)
                  .Width(80).Title("Entity Id");
                columns.Bound(c => c.NameOfInstitution);
                columns.Bound(c => c.Addresses).ClientTemplate("#=generateAddress(Addresses)#").Title("Address");
                columns.Bound(c => c.InstitutionTelephones).ClientTemplate("#=generatePhone(InstitutionTelephones)#").Title("Phone");

            })
            .HtmlAttributes(new { style ="height: 750px;" })
            .Scrollable()
            .Groupable()
            .Sortable()
            .Pageable()
            .DataSource(dataSource => dataSource
                .Ajax()
                .PageSize(99)
                .Read(read => read.Action("GetList","Home"))
            ).NoRecords(x => x.Template("NO RECORDS")))

对于ToDataSourceResult,它是IEnumerable的方法。

对于GetAllVesselsAsync(),它返回一个任务。

尝试下面的代码

1
2
3
4
5
6
[HttpGet]
public async Task<DataSourceResult> GetVessels([DataSourceRequest]DataSourceRequest request)
{
    var result = await service.GetAllVesselsAsync();
    return result.ToDataSourceResult(request);
}

更新

1
2
3
4
5
6
7
public class HomeController : Controller
{
    private IVesselRepository service;
    public HomeController(IVesselRepository service)
    {
        this.service = service;
    }