I have a Grid that has Popup Editing and it all works using WebApi except for the Delete action. I can't figure out what I'm missing.
Here's my HTML code:
Here's my WebApi controller (with a base class):
Here's the WebApi Base Class that contains the HTTP CRUD operations:
And here's my WebApi Route configuration:
Here's the 404 message response:
It seems the "id" isn't getting into the route. When I tested this in Fiddler, it worked as long as I added the "id" as in:
http://localhost:port/api/receiptdocuments/delete/7
But the error message doesn't seem to be passing the "id" along with the request. It kind of looks like a route issue but I'm just not seeing it if it is. Any help here is appreciated.
Thanks.
Here's my HTML code:
01.
@(Html.Kendo().Grid(Model.ReceiptDocumentsList).Name("list")
02.
.Columns(columns =>
03.
{
04.
columns.Bound(c => c.DocumentName);
05.
columns.Bound(c => c.Title);
06.
columns.Bound(c => c.Userid);
07.
columns.Command(command => { command.Edit(); command.Destroy(); }).Width(180);
08.
})
09.
.ToolBar(toolbar => toolbar.Create())
10.
.Editable(editable => editable.Mode(GridEditMode.PopUp))
11.
.Pageable()
12.
.Sortable()
13.
.Scrollable()
14.
.DataSource(ds => ds
15.
.Ajax()
16.
.PageSize(20)
17.
.Events(events => events.Error("error_handler"))
18.
.Model(model => {
19.
model.Id(r => r.Id);
20.
})
21.
.Read(read => read.Url("/api/receiptdocuments").Type(HttpVerbs.Get))
22.
.Update(update => update.Url("/api/receiptdocuments/put").Type(HttpVerbs.Put))
23.
.Create(create => create.Url("/api/receiptdocuments/post").Type(HttpVerbs.Post))
24.
.Destroy(destroy => destroy.Url("/api/receiptdocuments/delete").Type(HttpVerbs.Delete))
25.
)
26.
)
27.
28.
29.
<
script
type
=
"text/javascript"
>
30.
function error_handler(e) {
31.
if (e.errors) {
32.
var message = "Errors:\n";
33.
$.each(e.errors, function (key, value) {
34.
if ('errors' in value) {
35.
$.each(value.errors, function () {
36.
message += this + "\n";
37.
});
38.
}
39.
});
40.
alert(message);
41.
}
42.
}
43.
</
script
>
Here's my WebApi controller (with a base class):
01.
public
class
ReceiptDocumentsController : BaseController<ReceiptDocuments>
02.
{
03.
#region ctors
04.
05.
private
readonly
IReceiptDocumentsService _receiptDocumentsService;
06.
07.
private
readonly
IUnitOfWork _unitOfWork;
08.
09.
public
ReceiptDocumentsController(IReceiptDocumentsService receiptDocumentsService, IUnitOfWork unitOfWork) :
base
(receiptDocumentsService, unitOfWork)
10.
{
11.
this
._receiptDocumentsService = receiptDocumentsService;
12.
this
._unitOfWork = unitOfWork;
13.
}
14.
15.
#endregion
16.
17.
}
Here's the WebApi Base Class that contains the HTTP CRUD operations:
001.
/// <summary>
002.
/// This is the common base ApiController used for all controllers.
003.
/// This class handles all the basic CRUD operations for the WebApi functions.
004.
/// </summary>
005.
/// <typeparam name="T"></typeparam>
006.
public
class
BaseController<T> : ApiController where T : Entity
007.
{
008.
#region ctors
009.
protected
readonly
IService<T> _service;
010.
011.
private
readonly
IUnitOfWork _unitOfWork;
012.
013.
public
BaseController(IService<T> service, IUnitOfWork unitOfWork)
014.
{
015.
this
._service = service;
016.
this
._unitOfWork = unitOfWork;
017.
}
018.
019.
#endregion
020.
021.
#region Basic CRUD
022.
023.
/// <summary>
024.
/// Get all the Products in the repository.
025.
/// </summary>
026.
/// <returns></returns>
027.
public
IEnumerable<T> Get()
028.
{
029.
return
_service.Get();
030.
}
031.
032.
/// <summary>
033.
/// Get the selected Product.
034.
/// </summary>
035.
/// <param name="id">Id</param>
036.
/// <returns></returns>
037.
public
T Get(
int
id)
038.
{
039.
T model = _service.GetById(id);
040.
if
(model ==
null
)
041.
throw
new
HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
042.
043.
return
model;
044.
}
045.
046.
/// <summary>
047.
/// Insert a new Product into the repository.
048.
/// </summary>
049.
/// <param name="model">Product</param>
050.
/// <returns></returns>
051.
public
HttpResponseMessage Post(T model)
052.
{
053.
if
(ModelState.IsValid)
054.
{
055.
_service.Insert(model);
056.
_unitOfWork.Commit();
057.
058.
var response = Request.CreateResponse(HttpStatusCode.Created, model);
059.
response.Headers.Location =
new
Uri(Url.Link(
"DefaultApi"
,
new
{ id = model.Id }));
060.
061.
return
response;
062.
}
063.
else
064.
{
065.
throw
new
HttpResponseException(
new
HttpResponseMessage(HttpStatusCode.BadRequest));
066.
}
067.
}
068.
069.
/// <summary>
070.
/// Update the selected Product.
071.
/// </summary>
072.
/// <param name="id">Id</param>
073.
/// <param name="model">Product</param>
074.
/// <returns></returns>
075.
public
HttpResponseMessage Put(T model)
076.
{
077.
if
(ModelState.IsValid)
078.
{
079.
try
080.
{
081.
_service.Update(model);
082.
_unitOfWork.Commit();
083.
}
084.
catch
(Exception)
085.
{
086.
return
Request.CreateResponse(HttpStatusCode.NotFound);
087.
}
088.
return
Request.CreateResponse(HttpStatusCode.OK, model);
089.
}
090.
else
091.
{
092.
return
Request.CreateResponse(HttpStatusCode.BadRequest);
093.
}
094.
}
095.
096.
/// <summary>
097.
/// Delete the selected Product.
098.
/// </summary>
099.
/// <param name="id">Id</param>
100.
/// <returns></returns>
101.
public
HttpResponseMessage Delete(
int
id)
102.
{
103.
T model = _service.GetById(id);
104.
if
(model ==
null
)
105.
{
106.
return
Request.CreateResponse(HttpStatusCode.NotFound);
107.
}
108.
109.
try
110.
{
111.
_service.Delete(model);
112.
_unitOfWork.Commit();
113.
}
114.
catch
(Exception)
115.
{
116.
return
Request.CreateResponse(HttpStatusCode.NotFound);
117.
}
118.
119.
return
Request.CreateResponse(HttpStatusCode.OK, model);
120.
}
121.
#endregion
122.
123.
}
And here's my WebApi Route configuration:
01.
public
static
class
WebApiConfig
02.
{
03.
public
static
void
Register(HttpConfiguration config)
04.
{
05.
config.Routes.MapHttpRoute(name:
"ReceiptDocuments"
,
06.
routeTemplate:
"api/receiptdocuments/{action}/{id}"
,
07.
defaults:
new
{ controller =
"ReceiptDocuments"
, action =
"Get"
, id = RouteParameter.Optional });
08.
09.
10.
config.Routes.MapHttpRoute(
11.
name:
"DefaultApi"
,
12.
routeTemplate:
"api/{controller}/{id}"
,
13.
defaults:
new
{ id = RouteParameter.Optional }
14.
);
15.
}
16.
}
Here's the 404 message response:
1.
{
"Message"
:
"No HTTP resource was found that matches the request URI 'http://localhost:59723/api/receiptdocuments/delete'."
,
"MessageDetail"
:
"No action was found on the controller 'ReceiptDocuments' that matches the request."
}
It seems the "id" isn't getting into the route. When I tested this in Fiddler, it worked as long as I added the "id" as in:
http://localhost:port/api/receiptdocuments/delete/7
But the error message doesn't seem to be passing the "id" along with the request. It kind of looks like a route issue but I'm just not seeing it if it is. Any help here is appreciated.
Thanks.