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

CRUD server response, or repeating CRUD operations

22 Answers 461 Views
Data Source
This is a migrated thread and some comments may be shown as answers.
David
Top achievements
Rank 1
David asked on 03 Aug 2012, 10:15 PM
Hi;

I'm using .NET web methods to deliver CRUD services to my datasources. I am having a strange issue wherein every time I perform either a create or delete operation previous such operations are duplicated. For instance if I create a record it will call the create method once, but the next time it will call the method twice: once with the new data and once to duplicate the first call. With each new method call all previous create and delete calls are duplicated.

I suspect that the datasource is not getting an expected response from the server so it mistakenly believes that previous operations failed, queues them, and tries again on the next operation.

All my create and destroy web methods take POST operations, and merely absorb the incoming data without replying with data. In fact they are VB.NET subs with no return values. They typically have a small number of string arguments that are passed to a stored procedure in a remote database. Hence my datasource transport has a parametermap function that for all operations simply returns the arguments "stringified" for JSON.

Any idea why the datasource is repeating the create and destroy operations?

22 Answers, 1 is accepted

Sort by
0
Brett
Top achievements
Rank 2
answered on 30 Sep 2012, 06:52 PM
Is there any response to this? I am having the same issue. I followed the tutorials in the Kendo UI documentation, so I should not expect this to be happening.

All prior CRUD operations are being repeated. In my case, I create (POST) a new record. Then I update (PUT) an existing record. Once I click Update, the previous record I created, gets POSTed again, and then my existing record gets updated. As a side effect, the popup editor dialog does not close. If I click update again, a third POST of the previous "new" record is created again, and the record I just updated gets updated again.

This is very odd behavior.

UPDATE:

I figured it out based on the replies in another related forum post. The key here is that your Post method returns the newly created entity. If you don't, the id of the entity you just added to your grid never gets changed to its generated id in your database. Therefore, the entity in your grid is always "dirty" and keeps getting posted on subsequent POST/PUT actions.

It would be helpful if the Tutorial documentation presented a working Create action for the Kendo DataSource. I find it odd that all of the other actions are represented well (read, update, and delete), but not create.
0
David
Top achievements
Rank 1
answered on 01 Oct 2012, 03:36 PM
You said it, brother.
0
Christophla
Top achievements
Rank 1
answered on 20 Oct 2012, 07:31 AM
Agreed! I've been having a heck of a time just doing simple form CRUD operations. The only demo's they provide seem to be for grids...
0
German
Top achievements
Rank 1
answered on 26 Oct 2012, 01:15 PM
I'm having the same issue. What would the solution to this be? I've manually set the Id to the entity being added to see if the grid consider it as already added but no luck
0
David
Top achievements
Rank 1
answered on 27 Oct 2012, 03:24 PM
You have to make sure that the editor gets back the item that is being edited. That way it can update its data model after the operation.
0
German
Top achievements
Rank 1
answered on 29 Oct 2012, 12:22 PM
Yes, I was doing that (I think) but now I found the issue that was firing multiple times the Add action. For what I've found, the data that was returned to the controller had an error with a Datetime field (now I need to find what error is). That error made the record to be added to the repository but for some reason it was not marked as saved to the grid. So, when I added another record, the grid was firing again for the record added before. All I did was comment out the property in the class definition (until I find the error)and that was it, the add method was only called once per record.

The returned to Add is:
{"Data":[{"Id":1773740819...[ommited]...}],"Total":1,"AggregateResults":null,"Errors":{"FechaNacimiento":{"errors":["El valor \u002729/10/2012 09:14:44 a.m.\u0027 no es válido para FechaNacimiento."]}}}

So, for anybody who's experiencing this issue, check the returned data to the controller for errors

Hope I was clear with the explanation, my english is not so good
0
angella
Top achievements
Rank 1
answered on 12 Dec 2012, 12:05 PM
Hi I have some problem,
For instance if I create a record it will call the create method once, but the next time it will call the method twice: once with the new data and once to duplicate the first call. With each new method call all previous create and delete calls are duplicated,....
while reloading the page
0
Daniel
Telerik team
answered on 17 Dec 2012, 08:13 AM
Hi,

As Brett wrote - the item with the updated ID needs to be returned from the server in order to avoid posting the item again the next time the DataSource is synchronized. The ID is used by the DataSource to determine if the item is new and the ID will not be updated without returning it with the response.

Regards,
Daniel
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
angella
Top achievements
Rank 1
answered on 17 Dec 2012, 09:10 AM
My problem is different.
All prior CRUD operations are being repeated. In my case, first I create (POST) a new record without any problem. Then I update (PUT) an existing record without reloading the page. Once I click Update,  gets POSTed twice. Now, I want delete an item, Once I click delete,  gets POSTed third, and so on.
Seems the popup editor dialog does not close, And the post event repeated.
0
Daniel
Telerik team
answered on 17 Dec 2012, 09:29 AM
Hi,

Can you share a sample project which reproduces the problem or the full code you are using?

Regards,
Daniel
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
angella
Top achievements
Rank 1
answered on 17 Dec 2012, 09:45 AM
My related open/close Window script commands:
function ajaxCall(url, success, type) {
    $.ajax({
        url: url,
        success: function (html) {
            success(html);
        },
        type: type
    });
}
 
function wnd() {
    return $('#window').closest(".k-window-content").data("kendoWindow");
  }
 
function closeWindow() {
    var kendoWindow = $('#window').closest(".k-window-content").data("kendoWindow").close();
    return false;
}

function openWindow(url, title, windowName) {
    ajaxCall(url, function (html) {
        wnd(windowName).content(html);
        wnd(windowName).center();
        $('#' + windowName + '.k-window-content').height('auto').width('200px');
        wnd(windowName).title(title);
        wnd(windowName).open();
    });
}
0
angella
Top achievements
Rank 1
answered on 17 Dec 2012, 09:49 AM
It's my InsertUpdate Partial View:
@model KendoSample.Models.UserEntity
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
 
@{
    Layout = null;
}
 
@using (Ajax.BeginForm("InsertUpdate","User",null,new AjaxOptions() { OnSuccess = "OperationComplete" ,HttpMethod= "POST"},new {id="frmInsert"}))
{
<div>
    @Html.ValidationSummary(true)
    @Html.Hidden("Identifier")
    @Html.Hidden("IsUpdate")
    <fieldset class="t-edit-form-container" >
        <legend>Content</legend>
        <div class="editor-label">
            @Html.LabelFor(model => model.UserName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.UserName) 
            @Html.ValidationMessageFor(model => model.UserName, "*")
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.Email)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Email)
            @Html.ValidationMessageFor(model => model.UserName, "*")
 
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.PostId)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.PostId)
 
        </div>
    </fieldset>
    <div>
        @{Html.Kendo().Menu()
              .Name("footerMenu")
              .Items(item =>
              {
                  item.Add().Text("Save").ImageUrl("~/Content/images/Save.png").HtmlAttributes(new { onclick = "$('form').submit();" });
                  item.Add().Text("Cancel").ImageUrl("~/Content/images/Cancel.png").HtmlAttributes(new { onclick = "return closeWindow();" });
              })
              .Render();
        }
    </div>
</div>
}
0
Daniel
Telerik team
answered on 20 Dec 2012, 07:55 AM
Hi,

The code you provided does not seem to use the Kendo DataSource in any way which is the topic of this thread. Multiple requests made in your scenario indicates that there is an event bound multiple times. If the partial view is loaded each time after an update, this would be caused by adding jquery.unobtrusive-ajax.min.js in the partial view.

Regards,
Daniel
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
angella
Top achievements
Rank 1
answered on 22 Dec 2012, 05:36 AM
Hi Daniel,
Thank you much, fixed it.
The problem associated with this:

<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
0
Thomas
Top achievements
Rank 1
answered on 22 Apr 2013, 04:37 AM
Edited - turned out to be an issue with my code, my event handler was being attached multiple times.
0
Thomas
Top achievements
Rank 1
answered on 24 Apr 2013, 10:22 PM
 
0
Steven
Top achievements
Rank 1
answered on 20 Apr 2015, 09:01 PM

I need to know the code to post back my primaryID to the grid so I don't get duplications. When adding records.

 Here is my current code:

         public ActionResult Loading_Create([DataSourceRequest] DataSourceRequest request, Models.FacultyLoading facultyload)
        {

            if (facultyload != null && ModelState.IsValid)
            {
                FacultyLoading fl = new FacultyLoading();

                fl.Responsibility = facultyload.Responsibility;
                fl.YearTerm = facultyload.YearTerm;
                fl.RouteID = facultyload.RouteID;
                fl.Notes = facultyload.Notes;
                fl.LoadFactor = facultyload.LoadFactor;
                fl.LoadPrcnt = facultyload.LoadPrcnt;
                fl.CreditHours = facultyload.CreditHours;
                fl.ScholarshipPrcnt = facultyload.ScholarshipPrcnt;
                fl.CitizenshipPrcnt = facultyload.CitizenshipPrcnt;
                fl.TotalLoad = facultyload.TotalLoad;
                db.FacultyLoadings.Add(fl);       // How can I change this to return the primary key from the Server to the grid?


                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return Json(new[] { facultyload }.ToDataSourceResult(request, ModelState));
        }

 

 

 

 

I have seen this code with a possible fix on another thread. I tried assigning it to my facultyload.LID but got errors.

 Steve

 -----------------

 I had the same issue. The resolution is to set the primary key after
the update. The demos use a repository class so its not that clear what
is going on. Here is the code I use, old (broken) and new (fixed):



Old: the entity model has an "Add" function that does its thing and
returns the new primarykey int. The entity is being updated in the
business model with the new primarykey, but isn't passing back for
whatever reason.


[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Customer_Create([DataSourceRequest] DataSourceRequest request, CustomerModel entity)
{
    if (entity != null && ModelState.IsValid)
    {
        entity.Add();
    }
 
    return Json(new[] { entity }.ToDataSourceResult(request, ModelState));
}

New: Now, simply use the returned int and set the primarykey (id) to it. Pass back to Kendo. All good now.


[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Customer_Create([DataSourceRequest] DataSourceRequest request, CustomerModel entity)
{
    if (entity != null && ModelState.IsValid)
    {
          entity.Id =entity.Add();
    }
 
    return Json(new[] { entity }.ToDataSourceResult(request, ModelState));
}

 

----------------

0
Daniel
Telerik team
answered on 23 Apr 2015, 01:58 PM
Hello,

Actually the new ID should be assigned after saving the changes:
db.FacultyLoadings.Add(fl);
db.SaveChanges();
facultyload.LID = fl.LID;
Also, a RedirectToAction result should not be used when the grid is configured for Ajax binding.

Regards,
Daniel
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Steven
Top achievements
Rank 1
answered on 23 Apr 2015, 04:06 PM
Thank you very much! It worked exactly like you said.  Thanks for the extra tip as well.
0
Michael
Top achievements
Rank 2
Iron
answered on 15 Sep 2015, 02:34 PM
This is all fine and well but your examples on this are pathetic.  If you say you support angular then show real-life examples of the datasource transport actions (create, update) using angular service functions and handling the response and honoring the promises that are returned by $http function calls therein.  You're getting as bad as Infragistics was the documentation and support and that is the reason why I dropped them in favor of you guys - don't force me to make that decisions again.
0
Atanas Korchev
Telerik team
answered on 18 Sep 2015, 01:16 PM
Hi Michael,

Here is a real-life demo from our documentation which shows how to use $http and its promises.

The relevant code is this:

            transport: {
                read: function (e) {
                  $http.jsonp('http://demos.telerik.com/kendo-ui/service/Products?callback=JSON_CALLBACK').
                  success(function(data, status, headers, config) {
                      e.success(data)
                  }).
                  error(function(data, status, headers, config) {
                      alert('something went wrong')
                      console.log(status);
                  });
              }

Implementing the create, update and destroy methods is similar.

Regards,
Atanas Korchev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Chandler
Top achievements
Rank 1
answered on 21 Oct 2015, 02:08 PM

Hopefully this helps someone.. using MVC and some version of Kendo UI from 2013.

 

If the ModelState has errors, Kendo thinks that something went wrong and will try to duplicate the request later. My "Add" functions were working correctly because I was doing a "ModelState.IsValid" check in the controller.. But, for my deletes, all I cared about was getting the ID.. So I wasn't doing a check on the ModelState before removing the item. And, it turned out that there were ModelState errors when I was performing my "Delete" action. This causes subsequent requests to attempt to remove those items again. So, I updated my controller "Delete" action so that upon successfully deleting the object server-side, I'd remove all model errors.. Like so..

 

if (mSuccessDelete)
{
   // It was successful. Remove all model state errors so Kendo does not think something went wrong.
   foreach (var modelValue in ModelState.Values)
   {
       modelValue.Errors.Clear();
   }

   return Json(ModelState.ToDataSourceResult());
}​

 

Regards,

Tags
Data Source
Asked by
David
Top achievements
Rank 1
Answers by
Brett
Top achievements
Rank 2
David
Top achievements
Rank 1
Christophla
Top achievements
Rank 1
German
Top achievements
Rank 1
angella
Top achievements
Rank 1
Daniel
Telerik team
Thomas
Top achievements
Rank 1
Steven
Top achievements
Rank 1
Michael
Top achievements
Rank 2
Iron
Atanas Korchev
Telerik team
Chandler
Top achievements
Rank 1
Share this question
or