@@ -141,75 +141,230 @@ Additionally, you can use the `server-operation` or `.ServerOperation` property
141141``` 
142142
143143## WebAPI DataSource  
144+   
145+ The WebAPI DataSource maps the CRUD operations to standard HTTP verbs (` GET ` , ` POST ` , ` PUT ` , ` DELETE ` ) and supports the following data operations:
144146
145- The WebAPI DataSource type of data binding is designed for WebAPI projects and works in the same way as the Ajax data source.
147+ -  Paging  
148+ -  Sorting  
149+ -  Filtering  
150+ -  Grouping and Aggregates  
146151
147152``` HtmlHelper 
148-      @(Html.Kendo().DataSource<OrderViewModel>() 
149-         .Name("myDataSource") 
150-         .WebApi(dataSource => 
153+ @(Html.Kendo().DataSource<ProductViewModel>() 
154+     .Name("myDataSource") 
155+     .WebApi(webapi => 
156+     { 
157+         webapi.Read(read => read.Action("Get", "Product")); 
158+         webapi.Create(create => create.Action("Post", "Product")); 
159+         webapi.Update(update => update.Action("Put", "Product", new { id = "{0}" })); 
160+         webapi.Destroy(destroy => destroy.Action("Delete", "Product", new { id = "{0}" })); 
161+         webapi.Model(model => 
151162        { 
152-           dataSource 
153-             .Read(read => read.Action("Get", "Product")) 
154- 	    	.Create(create => create.Action("Post", "Product")) 
155- 	    	.Update(update => update.Action("Put", "Product", new { id = "{0}"} )) 
156- 	    	.Destroy(destroy => destroy.Action("DELETE", "Product", new { id = "{0}" })) 
157-             .PageSize(2) 
158-             .ServerOperation(true) 
159-             .Model(model => 
160-             { 
161-                 model.Id(field => field.OrderID); 
162-                 model.Field(field => field.OrderID).Editable(false); 
163-             }); 
164-         }) 
165-     ) 
166- 
167-     <script> 
168-         $(document).ready(function () { 
169-             myDataSource.read(); // A GET request will be sent to the ProductController Get action 
163+             model.Id(p => p.ProductID); 
164+             model.Field(p => p.ProductName).DefaultValue("New Product"); 
170165        }); 
171-     </script>   
166+     }) 
167+ ) 
168+ 
169+ <script> 
170+     $(document).ready(function () { 
171+         myDataSource.read(); // A GET request will be sent to api/product 
172+     }); 
173+ </script> 
172174``` 
173175{% if site.core %}
174176``` TagHelper 
175-     <!-- When you use the WebAPI DataSource type of data binding in an editable Grid, define the field types in the `schema` to use the correct editors for the field. --> 
176- 
177-     <kendo-datasource name="myDataSource" type="DataSourceTagHelperType.WebApi" server-operation="true" page-size="2"> 
178-         <transport> 
179-             <read url="/api/product" action="get"/> 
180-             <update url="/api/product/{0}" action="put" /> 
181-             <create url="/api/product" action="post"/> 
182-             <destroy url="/api/product/{0}" action="delete"/> 
183-         </transport> 
184-         <schema> 
185-             <model id="OrderID"> 
186-                 <fields> 
187-                     <field name="OrderID" type="number" editable="false"></field> 
188-                 </fields> 
189-             </model> 
190-         </schema> 
191-     </kendo-datasource> 
192- 
193-     <script> 
194-         $(document).ready(function () { 
195-             myDataSource.read(); // A GET request will be sent to the ProductController Get action 
196-         }); 
197-     </script>  
177+ @addTagHelper *, Kendo.Mvc 
178+ 
179+ <kendo-datasource name="myDataSource" type="DataSourceTagHelperType.WebApi"> 
180+     <transport> 
181+         <read url="/aspnet-core/api/product" type="GET"/> 
182+         <create url="/aspnet-core/api/product" type="POST"/> 
183+         <update url="/aspnet-core/api/product/{0}" type="PUT"/> 
184+         <destroy url="/aspnet-core/api/product/{0}" type="DELETE"/> 
185+     </transport> 
186+     <schema> 
187+         <model id="ProductID"> 
188+             <fields> 
189+                 <field name="ProductID" type="number" editable="false"></field> 
190+                 <field name="ProductName" type="string" default-value="New Product"></field> 
191+                 <field name="UnitPrice" type="number"></field> 
192+                 <field name="UnitsInStock" type="number"></field> 
193+                 <field name="Discontinued" type="boolean"></field> 
194+             </fields> 
195+         </model> 
196+     </schema> 
197+ </kendo-datasource> 
198+ 
199+ <script> 
200+     $(document).ready(function () { 
201+         myDataSource.read(); // A GET request will be sent to api/product 
202+     }); 
203+ </script> 
198204``` 
199- {% endif %}
200205``` C#  ProductController
206+ [ApiController ]
207+ [Route (" api/[controller]"  )]
208+ public  class  ProductController  : Controller 
209+ {
210+     private  readonly  IProductService  service ;
211+ 
212+     public  ProductController (IProductService  productService )
213+     {
214+         service  =  productService ;
215+     }
201216
217+     //  GET: api/product 
202218     [HttpGet ]
203- 	 public  DataSourceResult  Get ([DataSourceRequest ]DataSourceRequest  request )
219+      public  DataSourceResult  Get ([DataSourceRequest ]  DataSourceRequest  request )
204220    {
205-         //  Orders can be IQueriable or IEnumerable. 
206-         //  The result is a filtered, paged, grouped, and sorted collection. 
207-          var  result  =  orders .ToDataSourceResult (request );
221+         return  service .Read ().ToDataSourceResult (request );
222+     }
208223
209-         //  response object : { AggregateResults: [], Data: [{},{}], Errors: null, Total: 7 } 
210-          return  result ;
224+     //  POST: api/product 
225+      [HttpPost ]
226+     public  IActionResult  Post ([FromForm ] ProductViewModel  product )
227+     {
228+         if  (! ModelState .IsValid )
229+         {
230+             return  BadRequest (
231+                 ModelState .Values 
232+                     .SelectMany (v  =>  v .Errors )
233+                     .Select (error  =>  error .ErrorMessage )
234+             );
235+         }
236+ 
237+         service .Create (product );
238+ 
239+         return  new  ObjectResult (
240+             new  DataSourceResult 
241+             {
242+                 Data  =  new [] { product  },
243+                 Total  =  1 
244+             }
245+         );
246+     }
247+ 
248+     //  PUT: api/product/{id} 
249+      [HttpPut (" {id}"  )]
250+     public  IActionResult  Put (int  id , [FromForm ] ProductViewModel  product )
251+     {
252+         if  (ModelState .IsValid  &&  id  ==  product .ProductID )
253+         {
254+             try 
255+             {
256+                 service .Update (product );
257+             }
258+             catch  (DbUpdateConcurrencyException )
259+             {
260+                 return  NotFound ();
261+             }
262+ 
263+             return  Ok ();
264+         }
265+ 
266+         return  BadRequest (
267+             ModelState .Values 
268+                 .SelectMany (v  =>  v .Errors )
269+                 .Select (error  =>  error .ErrorMessage )
270+         );
271+     }
272+ 
273+     //  DELETE: api/product/{id} 
274+      [HttpDelete (" {id}"  )]
275+     public  IActionResult  Delete (int  id )
276+     {
277+         try 
278+         {
279+             service .Destroy (new  ProductViewModel  { ProductID  =  id  });
280+         }
281+         catch  (DbUpdateConcurrencyException )
282+         {
283+             return  NotFound ();
284+         }
285+ 
286+         return  Ok ();
287+     }
288+ }
289+ ``` 
290+ {% endif %}
291+ {% if site.mvc %}
292+ ``` C#  ProductController
293+ public  class  ProductController  : System .Web .Http .ApiController 
294+ {
295+     ProductService  service ;
296+     public  ProductController ()
297+     {
298+         service  =  new  ProductService (new  DemoDBContext ());
299+     }
300+     protected  override  void  Dispose (bool  disposing )
301+     {
302+         service .Dispose ();
303+         base .Dispose (disposing );
304+     }
305+     //  GET api/product 
306+      public  DataSourceResult  Get ([System .Web .Http .ModelBinding .ModelBinder (typeof (WebApiDataSourceRequestModelBinder ))]DataSourceRequest  request )
307+     {
308+         return  service .Read ().ToDataSourceResult (request );
309+     }
310+     //  POST api/product 
311+      public  HttpResponseMessage  Post (ProductViewModel  product )
312+     {
313+         if  (ModelState .IsValid )
314+         {
315+             service .Create (product );
316+             var  response  =  Request .CreateResponse (HttpStatusCode .Created , new  DataSourceResult  { Data  =  new [] { product  }, Total  =  1  });
317+             response .Headers .Location  =  new  Uri (Url .Link (" DefaultApi"  , new  { id  =  product .ProductID  }));
318+             return  response ;
319+         }
320+         else 
321+         {
322+             var  errors  =  ModelState .Values .SelectMany (v  =>  v .Errors ).Select (error  =>  error .ErrorMessage );
323+             return  Request .CreateResponse (HttpStatusCode .BadRequest , errors );
324+         }
325+     }
326+     //  PUT api/product/5 
327+      public  HttpResponseMessage  Put (int  id , ProductViewModel  product )
328+     {
329+         if  (ModelState .IsValid  &&  id  ==  product .ProductID )
330+         {
331+             try 
332+             {
333+                 service .Update (product );
334+             }
335+             catch  (DbUpdateConcurrencyException )
336+             {
337+                 return  Request .CreateResponse (HttpStatusCode .NotFound );
338+             }
339+             return  Request .CreateResponse (HttpStatusCode .OK );
340+         }
341+         else 
342+         {
343+             var  errors  =  ModelState .Values .SelectMany (v  =>  v .Errors ).Select (error  =>  error .ErrorMessage );
344+             return  Request .CreateResponse (HttpStatusCode .BadRequest , errors );
345+         }
346+     }
347+     //  DELETE api/product/5 
348+      public  HttpResponseMessage  Delete (int  id )
349+     {
350+         ProductViewModel  product  =  service .Read ().FirstOrDefault (p  =>  p .ProductID  ==  id );
351+         if  (product  ==  null )
352+         {
353+             return  Request .CreateResponse (HttpStatusCode .NotFound );
354+         }
355+         try 
356+         {
357+             service .Destroy (product );
358+         }
359+         catch  (DbUpdateConcurrencyException )
360+         {
361+             return  Request .CreateResponse (HttpStatusCode .NotFound );
362+         }
363+         return  Request .CreateResponse (HttpStatusCode .OK , product );
211364    }
365+ }
212366``` 
367+ {% endif %}
213368
214369## Custom DataSource  
215370
0 commit comments