WebApi datasource not working - Error 415

1 Answer 26 Views
Grid
Daniel
Top achievements
Rank 1
Iron
Iron
Veteran
Daniel asked on 11 Aug 2021, 02:02 PM | edited on 13 Aug 2021, 10:55 AM

Hey guys,

I'm actually new to WebApi and I have a Kendo Grid with the WebApi() option activated:

@(Html.Kendo().Grid<OfferType>()
              .Name("grid")
              .Columns(columns =>
              {
                  columns.Bound(p => p.Name);
                  columns.Command(command => { command.Edit(); });
              })
              .DataSource(dataSource =>
                  dataSource
                    .WebApi()
                    .Model(model =>
                    {
                        model.Id(p => p.ID);
                    })
                    .Events(events => events.Error("error_handler"))
                    .Read(read => read.Url("https://localhost:44362/api/OfferType"))
                    .Update(update => update.Url("https://localhost:44362/api/OfferType/{0}"))
              )
              .Pageable()
              .Sortable()
	)

 

In your demo für .NET Core you're using the view inside a webapi-project. This is not my case. I'm using the grid in a project which has to be connected to a webapi outside the project/solution. Therefore I have to use "read => read.Url("xyz")" (I think) to get connection to my outside hosted webapi. Because via "read.Action(x,y)" I can't refer to other projects/solutions and urls.

The controller of my webapi is looking like that:

    [Route("api/[controller]")]
    [ApiController]
    public class OfferTypeController : ControllerBase
    {
        private readonly FrueheHilfenContext _context;

        public OfferTypeController(FrueheHilfenContext context)
        {
            _context = context;
        }



        [HttpGet]
        [EnableCors("AllowLocal")]
        public DataSourceResult Get([DataSourceRequest] DataSourceRequest request)
        {
            List<OfferType> returnList = new List<OfferType>();
            using (_context)
            {
                returnList = _context.OfferTypes.ToList();
            }
            
            return returnList.ToDataSourceResult(request);
        }

        // PUT api/<OfferTypeController>/5
        [HttpPut("{id}")]
        [EnableCors("AllowLocal")]
        public IActionResult Put(int id, OfferType offerType)
        {
            if (ModelState.IsValid && id == offerType.ID)
            {
                try
                {
                    using (_context)
                    {
                        _context.Entry(offerType).State = EntityState.Modified;
                        _context.SaveChanges();
                    }
                }
                catch (DbUpdateConcurrencyException)
                {
                    return new NotFoundResult();
                }

                return new StatusCodeResult(200);
            }
            else
            {
                return BadRequest(ModelState.Values.SelectMany(v => v.Errors).Select(error => error.ErrorMessage));
            }
        }
    }

 

Getting data is working like expected. But I have problems to update my data via put. The console is giving me the errorcode 415 "unsupported media type". When debugging my webapi project the put actions is never been called. So I think there is something wrong with my setup of the grid.

Edit: I know why I'm getting the 415 error (see my answer in the comments). I found out that when I expect a datasourcerequest as an argument in the put-action (so a "[DataSourceRequest] DataSourceRequest offerType" instead of a "OfferType offerType") the action is successfully called without errors. But with the datasourcerequest there aren't any infos about my updated object in the grid. So my grid isn't sending the updated object but the metadata of the grid.

Is anybody seeing my mistake?

Daniel
Top achievements
Rank 1
Iron
Iron
Veteran
commented on 12 Aug 2021, 08:31 AM | edited

Also I try out to change the ".Update()" method to:

.Update(update => update.Url("https://localhost:44362/api/OfferType").Type(HttpVerbs.Put))

and in the webapi-controller

[HttpPut("Update")]
public IActionResult Put(OfferType offerType)
{
      ...
}
without success.
Daniel
Top achievements
Rank 1
Iron
Iron
Veteran
commented on 13 Aug 2021, 09:06 AM | edited

Okay, I found something. Instead of expecting my "OfferType" model in the put action I tried to achieve a DataSourceRequest and then my action is calling!

[HttpPut]
public void Put([DataSourceRequest] DataSourceRequest offerType)
{
}
But this is not helping me. I need the object which I updated and not the metadata of the grid. So it seems like the grid isn't sending the object data, only the metadata. What's wrong?
Daniel
Top achievements
Rank 1
Iron
Iron
Veteran
commented on 13 Aug 2021, 09:50 AM

I also tried to set up a webapi controller in the same project like my view with my grid. I called the controller like described in your demo via

.Update(create => create.Action("Put", "Home", new { id = "{0}"} )))
and also there I can receive only data when my argument is a datasourcerequest.

1 Answer, 1 is accepted

Sort by
0
Stoyan
Telerik team
answered on 16 Aug 2021, 02:08 PM

Hi Daniel,

Thank you for sharing your code.

The reported behavior in which the response of the WebAPI DataSource doesn't contain the JSON of the Grid's updated DataItems is expected and can be also replicated in our Grid WebApi DataSource Demo.

That being said you can subscribe to the Edit event of the Grid which exposes the Grid's DataItem and an isNew method to check whether the DataItem is newly created or updated:

 .Events(e => e.Edit("onEdit"))
function onEdit(e){
     if(e.model.isNew()){
         console.log(e.model);
     }
}

 

If the above doesn't prove useful in the scenario at hand, please consider providing additional details about the way you need to utilize the response data. Can you share the request submitted on update? This will allow me to provide more appropriate suggestions.

Regards,
Stoyan
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Daniel
Top achievements
Rank 1
Iron
Iron
Veteran
commented on 23 Aug 2021, 07:55 AM | edited

Well, the onEdit-Event isn't even fired because the error is preventing it.

With the above setup my grid is now sending 3 requests (1x error 204, 2x error 400) when I'm updating one dataset in the grid:

curl "https://localhost:44362/api/OfferType/1136" ^
  -X "OPTIONS" ^
  -H "authority: localhost:44362" ^
  -H "accept: */*" ^
  -H "access-control-request-method: PUT" ^
  -H "origin: https://localhost:44379" ^
  -H "user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36" ^
  -H "sec-fetch-mode: cors" ^
  -H "sec-fetch-site: same-site" ^
  -H "sec-fetch-dest: empty" ^
  -H "referer: https://localhost:44379/" ^
  -H "accept-language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7" ^
  --compressed ^
  --insecure &
curl "https://localhost:44362/api/OfferType/1136" ^
  -X "PUT" ^
  -H "authority: localhost:44362" ^
  -H "sec-ch-ua: ^\^"Chromium^\^";v=^\^"92^\^", ^\^" Not A;Brand^\^";v=^\^"99^\^", ^\^"Google Chrome^\^";v=^\^"92^\^"" ^
  -H "accept: */*" ^
  -H "sec-ch-ua-mobile: ?0" ^
  -H "user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36" ^
  -H "content-type: application/x-www-form-urlencoded; charset=UTF-8" ^
  -H "origin: https://localhost:44379" ^
  -H "sec-fetch-site: same-site" ^
  -H "sec-fetch-mode: cors" ^
  -H "sec-fetch-dest: empty" ^
  -H "referer: https://localhost:44379/" ^
  -H "accept-language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7" ^
  --data-raw "sort=&group=&filter=&SortOrder=0&ID=1136&Created=8^%^2F20^%^2F2021+5^%^3A53^%^3A19+PM&CreatedBy=1&Edited=8^%^2F20^%^2F2021+5^%^3A53^%^3A19+PM&EditedBy=1&IsActive=true&Name=Elternkurs+updated" ^
  --compressed ^
  --insecure &
curl "https://localhost:44362/api/OfferType/1136" ^
  -X "PUT" ^
  -H "authority: localhost:44362" ^
  -H "sec-ch-ua: ^\^"Chromium^\^";v=^\^"92^\^", ^\^" Not A;Brand^\^";v=^\^"99^\^", ^\^"Google Chrome^\^";v=^\^"92^\^"" ^
  -H "accept: */*" ^
  -H "sec-ch-ua-mobile: ?0" ^
  -H "user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36" ^
  -H "content-type: application/x-www-form-urlencoded; charset=UTF-8" ^
  -H "origin: https://localhost:44379" ^
  -H "sec-fetch-site: same-site" ^
  -H "sec-fetch-mode: cors" ^
  -H "sec-fetch-dest: empty" ^
  -H "referer: https://localhost:44379/" ^
  -H "accept-language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7" ^
  --data-raw "sort=&group=&filter=&SortOrder=0&ID=1136&Created=8^%^2F20^%^2F2021+5^%^3A53^%^3A19+PM&CreatedBy=1&Edited=8^%^2F20^%^2F2021+5^%^3A53^%^3A19+PM&EditedBy=1&IsActive=true&Name=Elternkurs+updated" ^
  --compressed ^
  --insecure
  1.  
Daniel
Top achievements
Rank 1
Iron
Iron
Veteran
commented on 23 Aug 2021, 08:01 AM | edited

Oooooookay, I found out that the problem is actually in my model. Somehow the grid can't send valid data for datetime fields of my model (see in my comment above, Created=8^%^2F20^%^2F2021+5^%^3A53^%^3A19+PM). So this is something new and I will investigate the problem. My grid is working with the webapi correctly and my post here is solved for now. I'll comment here again if there is still a problem with the grid and my webapi after I resolved my problem with the datetime.

Daniel
Top achievements
Rank 1
Iron
Iron
Veteran
commented on 23 Aug 2021, 08:57 AM

Solved by setting

.Culture("de-DE")
in the datasource part of my grid. Now everything works, thank you!
Tags
Grid
Asked by
Daniel
Top achievements
Rank 1
Iron
Iron
Veteran
Answers by
Stoyan
Telerik team
Share this question
or