This is a migrated thread and some comments may be shown as answers.

WebApi datasource - Resource not found

3 Answers 263 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Maurits
Top achievements
Rank 1
Maurits asked on 21 Nov 2016, 04:53 PM

Hi,

I'm currently validating the UI for ASP.NET Core grid component and I run into an issue with the WebApi datasource. When trying the fetch the data it tries to find the data on endpoint "localhost:50050/Customers" however the endpoint is located at the endpoint "localhost:50050/api/Customers". I am following the examples listed here: "http://demos.telerik.com/aspnet-core/grid/webapi". In the demo the route is also configured at "api/{controller}".

Is there any special route configuration I need to add somewhere?

My "Index.cshtml" looks like:

<div class="main">
    @(Html.Kendo().Grid<Customer>()
        .Name("customerGrid")
        .Columns(columns =>
        {
            columns.Bound(c => c.Id).Title("Tenant");
            columns.Bound(c => c.CompanyProfile.CompanyName).Title("Naam");
            columns.Bound(c => c.CompanyProfile.Domain).Title("Domein");
            columns.Bound(c => c.RelationshipToPartner).Title("Relatie");
        })
        .Scrollable()
        .Groupable()
        .Sortable()
        .Pageable(pageable => pageable
            .Refresh(true)
            .PageSizes(true)
            .ButtonCount(5))
        .DataSource(dataSource => dataSource
            .WebApi()
            .Model(model =>
            {
                model.Id(c => c.Id);
            })
            .Read(read => read.Action("Get", "Customer"))
        )
    )
</div>

My controller class:

public class CustomerController : Controller
{
    private readonly IAuthenticationService _authenticationService;
    private readonly ICustomerService _customerService;
    private readonly ISubscriptionService _subscriptionService;
    private readonly IUsageService _usageService;
 
    public CustomerController(
        IAuthenticationService authenticationService,
        ICustomerService customerService,
        ISubscriptionService subscriptionService,
        IUsageService usageService
        )
    {
        if(authenticationService == null)
            throw new ArgumentNullException(nameof(authenticationService));
        if (customerService == null)
            throw new ArgumentNullException(nameof(customerService));
        if (subscriptionService == null)
            throw new ArgumentNullException(nameof(subscriptionService));
        if(usageService == null)
            throw new ArgumentNullException(nameof(usageService));
 
        _authenticationService = authenticationService;
        _customerService = customerService;
        _subscriptionService = subscriptionService;
        _usageService = usageService;
    }
 
    // GET: /<controller>/
    public IActionResult Index()
    {
        return View();
    }
 
    [HttpGet, Route("api/Customers")]
    public async Task<object> Customers([DataSourceRequest]DataSourceRequest request)
    {
        var customers = await _customerService
            .GetCustomersAsync();
 
        return new { data = customers, totalCount = customers.Count };
    }
}

 

 

3 Answers, 1 is accepted

Sort by
0
Maurits
Top achievements
Rank 1
answered on 21 Nov 2016, 06:10 PM

I managed to solve it by using the "read.Url(...)" method instead of "read.Action(...)". Here is my updated code:

<div class="main">
    @(Html.Kendo().Grid<Customer>()
        .Name("customerGrid")
        .Columns(columns =>
        {
            columns.Bound(c => c.Id).Title("Tenant");
            columns.Bound(c => c.CompanyProfile.CompanyName).Title("Naam");
            columns.Bound(c => c.CompanyProfile.Domain).Title("Domein");
            columns.Bound(c => c.RelationshipToPartner).Title("Relatie");
        })
        .Scrollable()
        .Groupable()
        .Sortable()
        .Pageable(pageable => pageable
            .Refresh(true)
            .PageSizes(true)
            .ButtonCount(5))
        .DataSource(dataSource => dataSource
            .WebApi()
            .Model(model =>
            {
                model.Id(c => c.Id);
            })
            .Read(read => read.Url("api/Customers"))
        )
    )
</div>

 

0
Allan
Top achievements
Rank 1
answered on 30 Nov 2017, 12:47 AM

Thank you for adding the solution.  I have a similar issue, but my webapi is a "default" implementation with a different signature.

[HttpGet]
public IActionResult Get()
{
    var result = ReadService.GetAll();
    return Ok(result);
}

 

This works fine and I see all the records returned in response body as straight Json.  However, nothing appears in the grid.

@(Html.Kendo()
    .Grid<StudentListViewModel>()
    .Name("kendoListGrid")
    .Columns(columns =>
    {
        columns.Bound(entity => entity.FirstName);
        columns.Bound(entity => entity.LastName);
        columns.Bound(entity => entity.IsActive);
    })
    .DataSource(dataSource => dataSource
        .WebApi()
        .Events(events => events.Error("error_handler"))
        .Read(read => read.Url("http://localhost:36160/api/Students"))
        .PageSize(10)
    )
    .Filterable()
    .Resizable(x => x.Columns(true))
    .Pageable(pageable => pageable
        .Refresh(true)
        .PageSizes(true)
        .ButtonCount(5))
    .Navigatable(true)
    .Sortable(sortable => sortable
        .AllowUnsort(true)
        .SortMode(GridSortMode.SingleColumn))
    .Selectable(selectable => selectable
        .Type(GridSelectionType.Row)
        .Mode(GridSelectionMode.Single))
)

Do I have to include the Model section in the gridcode, and the [DataSourceRequest]DataSourceRequest request in the signature?  If so, would it be better to use an MVC controller in the current project to call the external site, instead of requesting the external data directly?

0
Stefan
Telerik team
answered on 04 Dec 2017, 11:49 AM
Hello, Allan,

I can suggest checking our demo for binding the Grid to WebApi. This is the code using for read:

public ProductController()
        {
            service = new ProductService(new SampleEntities());
        }


public DataSourceResult Get([System.Web.Http.ModelBinding.ModelBinder(typeof(WebApiDataSourceRequestModelBinder))]DataSourceRequest request)
       {
           return service.Read().ToDataSourceResult(request);
       }

http://demos.telerik.com/aspnet-mvc/grid/webapi

Also, the following article can prove helpful:

https://docs.telerik.com/aspnet-mvc/helpers/grid/editing/webapi-editing

As for which approach is better, this depends mostly on personal preference, both approaches with MVC Actions in the Controller and WebApi are supported. The only difference is that the MVC Controllers approach may have more examples for specific scenarios.

If the issue still occurs, please provide a fully runnable example and I will gladly inspect it.

Regards,
Stefan
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Tags
Grid
Asked by
Maurits
Top achievements
Rank 1
Answers by
Maurits
Top achievements
Rank 1
Allan
Top achievements
Rank 1
Stefan
Telerik team
Share this question
or