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

MVC5 WEB API CRUD - newbie question

8 Answers 92 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Gordon
Top achievements
Rank 1
Gordon asked on 06 Jun 2014, 01:53 PM
Hi,
Apologies in advance - just trying to get started with this, and to compound things, I'm new to WebAPI too.

I've taken the inline grid demo, and made a few adjustments.  I also used the MVC5 WebAPI template to create a new JSON service I could call, but can't seem to get it all working together.

The grid initializes properly, and does a GET to return and show the three rows.  However, when I attempt to update/create/delete, it always calls the POST method on the server, and the value passed is always unititialised.  Can someone please advise where I'm going wrong?

My model looks like this:

namespace WebAPI2.Models
{
public class Product
{
public int ProductID { get; set; }
public string ProductName {get;set;}
public int UnitPrice { get; set; }
public bool Discontinued { get; set; }
public int UnitsInStock { get; set; }
}
}

The controller:
namespace WebAPI2.Controllers
{
public class ProductsController : ApiController
{
Product[] products = new Product[]
{
new Product { ProductID = 1, ProductName = "Prod_1", UnitPrice = 1, Discontinued=false, UnitsInStock=1 },
new Product { ProductID = 2, ProductName = "Prod_2", UnitPrice = 2, Discontinued=true, UnitsInStock=2 },
new Product { ProductID = 3, ProductName = "Prod_3", UnitPrice = 3, Discontinued=false, UnitsInStock=3 },
};

// GET api/products
public IEnumerable<Product> Get()
{
return products;
}

// GET api/products/5
public Product Get(int id)
{
return products[id];
}

// POST api/products
public void Post([FromBody]Product value)
{
//just for a breakpoint
int i = 1;
}

// PUT api/products/5
public void Put(int id, [FromBody]Product value)
{
//just for a breakpoint
int i = 1;
}

// DELETE api/products/5
public void Delete(int id)
{
//just for a breakpoint
int i = 1;
}
}
}

And finally the client:
<div id="example">
<div id="grid"></div>

<script>
$(document).ready(function () {
var crudServiceBaseUrl = "http://demos.telerik.com/kendo-ui/service",
dataSource = new kendo.data.DataSource({
transport: {
read: {
//url: crudServiceBaseUrl + "/Products",
//dataType: "jsonp"
url: "http://localhost:63272/api/products",
dataType: "json",
type: "GET"
},
update: {
//url: crudServiceBaseUrl + "/Products/Update",
//dataType: "jsonp"
url: function (product) {
return "http://localhost:63272/api/products/" + product.ProductID;
},
dataType: "json",
type: "PUT"
},
destroy: {
//url: crudServiceBaseUrl + "/Products/Destroy",
//dataType: "jsonp"
url: function (product) {
return "http://localhost:63272/api/products/" + product.ProductID;
},
dataType: "json",
type: "DELETE"
},
create: {
//url: crudServiceBaseUrl + "/Products/Create",
//dataType: "jsonp"
url: "http://localhost:63272/api/products",
dataType: "json",
type: "POST"
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
}
},
batch: true,
pageSize: 20,
schema: {
model: {
//id: "ProductID",
fields: {
ProductID: { editable: false, nullable: true },
ProductName: { validation: { required: true } },
UnitPrice: { type: "number", validation: { required: true, min: 1 } },
Discontinued: { type: "boolean" },
UnitsInStock: { type: "number", validation: { min: 0, required: true } }
}
}
}
});

$("#grid").kendoGrid({
dataSource: dataSource,
pageable: true,
height: 550,
toolbar: ["create"],
columns: [
"ProductName",
{ field: "UnitPrice", title: "Unit Price", format: "{0:c}", width: "120px" },
{ field: "UnitsInStock", title: "Units In Stock", width: "120px" },
{ field: "Discontinued", width: "120px" },
{ command: ["edit", "destroy"], title: "&nbsp;", width: "200px" }],
editable: "inline"
});
});
</script>
</div>


Thanks in advance for any help!

8 Answers, 1 is accepted

Sort by
0
Accepted
Daniel
Telerik team
answered on 10 Jun 2014, 09:05 AM
Hi,

A request will always be made to the post method because the id field configuration seems to be commented:
model: {
    //id: "ProductID",
The model id field is used to determine if a model is a new one so the field needs to be specified in order for the dataSource to be able to determine the correct operation.
There are also a few other changes that are needed in order for the model to be posted correctly to the API controller:
  • Since a single item is expected for the API methods, batch operations should be disabled. 
  • If the data should be sent as JSON then you should set the requests contentType configuration to "application/json":
    update: {   
        url: function (product) {
            return "http://localhost:63272/api/products/" + product.ProductID;
        },
        dataType: "json",   
        type: "PUT",
        contentType: "application/json"
    },
    In this case and with disabled batch updates you should also serialize the entire options as JSON
    parameterMap: function (options, operation) {
        if (operation !== "read" && options) {
            return kendo.stringify(options);
        }
    }

    If the data should be sent with the default conentType(application/x-www-form-urlencoded) then you should not serialize the data as JSON in the parameterMap function.


Regards,
Daniel
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Gordon
Top achievements
Rank 1
answered on 10 Jun 2014, 11:49 AM
Thanks Daniel,
All seems to be working now.
0
Bertha
Top achievements
Rank 1
answered on 10 Jun 2014, 02:02 PM
Thanks.  I follow demo of previous telerik's examples and run into the same problem and solve by your post.
0
Bertha
Top achievements
Rank 1
answered on 10 Jun 2014, 03:38 PM
How do I capture the error status of web api 2 IHttpActionResult?
distinguish it is NotFound() or Conflict();

I try e[0] or e.xhr but it is undefined.  e is just a string "error".

schema: {
model: {
id: "ID",
fields: {
ID: {editable: false, nullable: false},
Username: { nullable: false, validation: { required: true } }
}
},
errors: "Errors"
},
error: function (e) {
var statusCode = e.xhr];
alert(statusCode);
if (statusCode == 409) {
alert("Username already exists!");
} else {
alert("Username not found");
}
this.cancelChanges();
}

Thanks.
0
Daniel
Telerik team
answered on 12 Jun 2014, 07:59 AM
Hello,

Could yo provide a sample that demonstrates the problem with the error event? There are not any known reasons for just a string to be passed as event argument.

Regards,
Daniel
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Bertha
Top achievements
Rank 1
answered on 12 Jun 2014, 01:43 PM
Not a problem on kendo ui.  I just don't know how to capture whether web api 2 is sending NotFound() or Conflict().

in my web api 2

 public IHttpActionResult Post([FromBody] Facility uu)
{
if (uu != null && uu.FacCode != "")
{
bool found = context.Facilities.Any(x => x.FacCode == uu.FacCode);
if (!found)
{
context.Facilities.Add(uu);
context.SaveChanges();
Facility n = context.Facilities.SingleOrDefault(x => x.FacCode == uu.FacCode);
return Ok(n);
}
}
return Conflict();   ???? or NotFound() =>  how to know it is Conflict() or NotFound()
}

In kendo,

error: function (e) {
alert("Region name already exists!");  =>  if (e.statuscode is 409, then alert("something else!!"); how to check????
this.cancelChanges();
}

0
Daniel
Telerik team
answered on 16 Jun 2014, 09:51 AM
Hello again,

The approach with the status code is correct if you wish to check the reason for the failed action:
error: function (e) {
    var statusCode = e.xhr.status;
 
    if (statusCode == 409) {
        alert("Username already exists!");
    } else if (statusCode == 404) {
        alert("Username not found");
    }
Returning custom errors is another option.

Regards,
Daniel
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Bertha
Top achievements
Rank 1
answered on 16 Jun 2014, 02:09 PM
Thanks.  Working correctly.
Tags
Grid
Asked by
Gordon
Top achievements
Rank 1
Answers by
Daniel
Telerik team
Gordon
Top achievements
Rank 1
Bertha
Top achievements
Rank 1
Share this question
or