0

I am using Kendo UI feature Grid and trying to implement batch Update functionality.

Here is what I have done so far:

           $(document).ready(function () {
             ("#grid").kendoGrid({
               dataSource:
                   {
                   type: "json",
                   transport:
                        {
                            read: function (options) {
                                $.ajax({
                                    url: "IndicatorService.svc/GetIndicators/" + speedID,
                                    dataType: "json",
                                    success: function (result) {
                                        options.success(result);
                                    }
                                });

                            },

                            update: function(options) {
                                $.ajax({
                                    type: "POST",
                                    url: "IndicatorService.svc/UpdateIndicators",
                                    dataType: "json",
                                    contentType: "application/json",
                                    data: {
                                        Indicators: kendo.stringify(options.data.models)
                                    },
                                    success: function(result) {
                                        // notify the data source that the request succeeded
                                        options.success(result);
                                    },
                                    error: function(result) {
                                        // notify the data source that the request failed
                                        options.error(result);
                                    }
                                });
                            }



                        },
                   batch: true,
                   schema: {
                       type: 'json',
                       model: {
                           id: "IndicatorUID",
                           fields: {
                               IndicatorUID: { type: "guid" },
                               IndicatorName: { type: "string" },
                               LastUpdatedBy: { type: "string" },
                               LastUpdatedDate: { type: "date" },
                               POPL3Commit: { type: "date" },
                               ActualFinish: { type: "date" },
                               PlanOfRecord: { type: "date" },
                               Trend: { type: "date" }

                           }
                       }
                   },
                   pageSize: 10

               },
               height: 430,
               filterable: true,
               sortable: true,
               pageable: true,
               toolbar: ["create", "save", "cancel"],
               editable: true,

               columns: [
                   {
                       field: "IndicatorName",
                       title: "IndicatorName",
                       width: 120
                   },
                   {
                       field: "POPL3Commit",
                       title: "POPL3Commit",
                       format: "{0:MM/dd/yyyy}",
                       width: 120
                   },
                   {
                       field: "PlanOfRecord",
                       title: "PlanOfRecord",
                       format: "{0:MM/dd/yyyy}",
                       width: 120
                   },
                   {
                       field: "Trend",
                       title: "Trend",
                       format: "{0:MM/dd/yyyy}",
                       width: 120
                   },
                   {
                       field: "ActualFinish",
                       title: "ActualFinish",
                       format: "{0:MM/dd/yyyy}",
                       width: 120
                   },
                   {
                       field: "LastUpdatedBy",
                       title: "LastUpdatedBy",
                       width: 120
                   },
                   {
                       field: "LastUpdatedDate",
                       title: "LastUpdatedDate",
                       width: 120
                   }
               ]
           });
       });

My View Model (IndicatorGridLineItem)

[DataContractAttribute]
public class IndicatorGridLineItem
{
    #region Private Properties

    /// <summary>
    /// Indicator UID
    /// </summary>
    private Guid _indicatorUID { get; set; }

    /// <summary>
    /// The _indicator name
    /// </summary>
    private string _indicatorName { get; set; }

    /// <summary>
    /// The _commit
    /// </summary>
    private DateTime _pOPL3Commit { get; set; }

    /// <summary>
    /// The _p OR
    /// </summary>
    private DateTime _planOfRecord { get; set; }

    /// <summary>
    /// The _trend
    /// </summary>
    private DateTime _trend { get; set; }

    /// <summary>
    /// The _trend color
    /// </summary>
    private string _trendColor { get; set; }

    /// <summary>
    /// The _actual finish
    /// </summary>
    private DateTime _actualFinish { get; set; }

    /// <summary>
    /// The _last updated by
    /// </summary>
    private string _lastUpdatedBy { get; set; }

    /// <summary>
    /// The _last updated date
    /// </summary>
    private DateTime _lastUpdatedDate { get; set; }

    #endregion Private Properties

    #region Public Properties

    /// <summary>
    /// Indicator UID
    /// </summary>
    [DataMember]
    public string IndicatorUID
    {
        get 
        { 
            return _indicatorUID.ToString(); 
        }
        set 
        {
            Guid newGuid;

            if (Guid.TryParse(value, out newGuid))
                _indicatorUID = newGuid;
            else
                _indicatorUID = Guid.Parse("00000000-0000-0000-0000-000000000000"); 
        }
    }

    /// <summary>
    /// The indicator name
    /// </summary>
    [DataMember]
    public string IndicatorName
    {
        get 
        { 
            return _indicatorName; 
        }
        set 
        { 
            _indicatorName = value; 
        }
    }

    /// <summary>
    /// The commit
    /// </summary>
    [DataMember]
    public string POPL3Commit
    {
        get 
        {
            return DateOutputGenerator(_pOPL3Commit); 
        }
        set 
        {
            _pOPL3Commit = DateInputGenerator(value);
        }
    }

    /// <summary>
    /// The POR
    /// </summary>
    [DataMember]
    public string PlanOfRecord
    {
        get 
        {    
            return DateOutputGenerator(_planOfRecord); 
        }
        set 
        { 
            _planOfRecord = DateInputGenerator(value); 
        }
    }

    /// <summary>
    /// The trend
    /// </summary>
    [DataMember]
    public string Trend
    {
        get 
        {    
            return DateOutputGenerator(_trend); 
        }
        set 
        { 
            _trend = DateInputGenerator(value); 
        }
    }

    /// <summary>
    /// The trend color
    /// </summary>
    [DataMember]
    public string TrendColor
    {
        get 
        {
            return String.IsNullOrEmpty(_trendColor) ? _trendColor : ""; 
        }
        set 
        { 
            _trendColor = value; 
        }
    }

    /// <summary>
    /// The actual finish
    /// </summary>
    [DataMember]
    public string ActualFinish
    {
        get 
        {    
            return DateOutputGenerator(_actualFinish); 
        }
        set 
        { 
            _actualFinish = DateInputGenerator(value); 
        }
    }

    /// <summary>
    /// The last updated by
    /// </summary>
    [DataMember]
    public string LastUpdatedBy
    {
        get 
        { 
            return String.IsNullOrEmpty(_lastUpdatedBy) ? _lastUpdatedBy : ""; 
        }
        set 
        { 
            _lastUpdatedBy = value; 
        }
    }
    /// <summary>
    /// The last updated date
    /// </summary>
    [DataMember]
    public string LastUpdatedDate
    {
        get 
        {    
            return DateOutputGenerator(_lastUpdatedDate); 
        }
        set 
        { 
            _lastUpdatedDate = DateInputGenerator(value); 
        }
    }

    #endregion Public Properties

    /// <summary>
    /// Dates the output generator.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    protected string DateOutputGenerator(DateTime value)
    {
        DateTime beginningOfTime = new DateTime();

        if (beginningOfTime.ToString().Equals(value.ToString()))
            return "";
        else
            return value.ToString();
    }

    /// <summary>
    /// Dates the input generator.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    protected DateTime DateInputGenerator(string value)
    {
        DateTime parsedDate;

        if (DateTime.TryParse(value, out parsedDate))
            return parsedDate;
        else
            return new DateTime();
    }
}

Here is the WCF Interface:

[ServiceContract]
public interface IIndicatorService
{
    [OperationContract]
    [WebGet(UriTemplate = "/GetIndicators/{SpeedId}", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
    List<IndicatorGridLineItem> GetIndicators(string SpeedId);

    [OperationContract]
    [WebInvoke(UriTemplate = "/UpdateIndicators", Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]  
    void UpdateIndicators(string Indicators);
}

Finally, here is the code for my Update Implementation inside the WCF Service:

    public void UpdateIndicators(string Indicators)
    {
        var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
        IEnumerable<IndicatorGridLineItem> foos = serializer.Deserialize<IEnumerable<IndicatorGridLineItem>>(Indicators);

    }

When I set a breakpoint inside this function here is what I am seeing for

string Indicators ="Indicators=%5B%7B%22ActualFinish%22%3Anull%2C%22IndicatorName%22%3A%22Ownership%22%2C%22IndicatorUID%22%3A%220ac1eb81-d44c-4b6a-9c3b-043537805cc7%22%2C%22LastUpdatedBy%22%3Anull%2C%22LastUpdatedDate%22%3Anull%2C%22POPL3Commit%22%3A%222013-11-26T08%3A00%3A00.000Z%22%2C%22PlanOfRecord%22%3Anull%2C%22Trend%22%3Anull%2C%22TrendColor%22%3Anull%7D%5D"

When the line IEnumerable foos = serializer.Deserialize>(Indicators); is executed while debugging I get the following ArgumentException: Invalid JSON primitive: Indicators.System.ArgumentException was unhandled by user code

HResult=-2147024809
Message=Invalid JSON primitive: Indicators.
Source=System.Web.Extensions
StackTrace:
   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializePrimitiveObject()
   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)
   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(String input, Int32 depthLimit, JavaScriptSerializer serializer)
   at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit)
   at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T](String input)
   at PDD_Web_UI.IndicatorService.UpdateIndicators(String Indicators) in c:\TFS-Newest\PCSO CSE\PDD Web UI\IndicatorService.svc.cs:line 23
   at SyncInvokeUpdateIndicators(Object , Object[] , Object[] )
   at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
InnerException: 

Also please note, I tried to modify the WCF Service parameter to use IEnumerable Indicators but was unable to hit the break point inside of my UpdateIndicators method at all without string Indicators as my parameter.

ComputerG33k
  • 151
  • 1
  • 2
  • 8

2 Answers2

1

Your JSON is being URL encoded - you should set data to an already serialized string:

transport: {
    read: {
        url: "IndicatorService.svc/GetIndicators/" + speedID
    },
    update: function (options) {
        $.ajax({
            type: "POST",
            url: "IndicatorService.svc/UpdateIndicators",
            dataType: "json",
            contentType: "application/json",
            data: kendo.stringify({ Indicators: options.data.models }),
            success: function (result) {
                options.success(result);
            },
            error: function (result) {
                options.error(result);
            }
        });
    }
},

Additionally, you should be able to use

void UpdateIndicators(List<Indicator> Indicators);

instead of

void UpdateIndicators(string Indicators);

on the server-side; I believe WCF will deserialize that for you.

Lars Höppner
  • 18,252
  • 2
  • 45
  • 73
  • Hey Lars, thanks for your reply now I am getting an error in kendo.web.min.js: Unhandled exception at line 13, column 26952 in http://localhost:23497/scripts/kendo/kendo.web.min.js - 0x800a03ec - Microsoft JScript runtime error: Expected ';' Interestingly, this file seems to have 3 parser errors when I open in Visual Studio and view it. – ComputerG33k Nov 27 '13 at 01:25
  • @user1710400 This is happening when you try to save? I'm not sure what the problem is - can you reference the unminified kendo.web.js in your project instead so you get the real line number (and the code in it)? Seeing that code might help track down the problem. Also: which version are you using? – Lars Höppner Nov 27 '13 at 01:39
  • I am no longer experiencing the Unhandled exception mentioned in my previous comment. I had to update the read code, please see my edited javascript above. I am still getting the same string back in my WCF service which I checked while debugging:"Indicators=%5B%7B%22ActualFinish%22%3Anull%2C%22IndicatorName%22%3A%22testing%22‌​%2C%22IndicatorUID%22%3A%2200000000-0000-0000-0000-000000000000%22%2C%22LastUpdat‌​edBy%22%3Anull%2C%22LastUpdatedDate%22%3Anull%2C%22POPL3Commit%22%3A%222013-11-27‌​T08%3A00%3A00.000Z%22%2C%22PlanOfRecord%22%3Anull%2C%22Trend%22%3Anull%2C%22Trend‌​Color%22%3Anull%7D%5D" – ComputerG33k Nov 27 '13 at 08:39
  • Hey Lars, I posted a solution in my answer to this question. Thanks for all your help! – ComputerG33k Nov 27 '13 at 09:02
  • @user1710400 updated solution...and I see you already figured it out yourself. Glad it's solved. – Lars Höppner Nov 27 '13 at 09:02
0

Ok I figured it out.

JS Code:

       $(document).ready(function () {
           $("#grid").kendoGrid({
               dataSource:
                   {
                   type: "json",
                   transport:
                        {
                            read: function (options) {
                                $.ajax({
                                    url: "IndicatorService.svc/GetIndicators/" + speedID,
                                    dataType: "json",
                                    success: function (result) {
                                        options.success(result);
                                    }
                                });

                            },

                            update: function(options) {
                                $.ajax({
                                    type: "POST",
                                    url: "IndicatorService.svc/UpdateIndicators",
                                    dataType: "json",
                                    contentType: "application/json",
                                    data: JSON.stringify( options.data.models ),
                                    success: function (result) {
                                        // notify the data source that the request succeeded
                                        options.success(result);
                                    },
                                    error: function (result) {
                                        // notify the data source that the request failed
                                        options.error(result);
                                    }
                                });
                            }



                        },
                   batch: true,
                   schema: {
                       type: 'json',
                       model: {
                           id: "IndicatorUID",
                           fields: {
                               IndicatorUID: { type: "guid" },
                               IndicatorName: { type: "string" },
                               LastUpdatedBy: { type: "string" },
                               LastUpdatedDate: { type: "date" },
                               POPL3Commit: { type: "date" },
                               ActualFinish: { type: "date" },
                               PlanOfRecord: { type: "date" },
                               Trend: { type: "date" }

                           }
                       }
                   },
                   pageSize: 10

               },
               height: 430,
               filterable: true,
               sortable: true,
               pageable: true,
               toolbar: ["create", "save", "cancel"],
               editable: true,

               columns: [
                   {
                       field: "IndicatorName",
                       title: "IndicatorName",
                       width: 120
                   },
                   {
                       field: "POPL3Commit",
                       title: "POPL3Commit",
                       format: "{0:MM/dd/yyyy}",
                       width: 120
                   },
                   {
                       field: "PlanOfRecord",
                       title: "PlanOfRecord",
                       format: "{0:MM/dd/yyyy}",
                       width: 120
                   },
                   {
                       field: "Trend",
                       title: "Trend",
                       format: "{0:MM/dd/yyyy}",
                       width: 120
                   },
                   {
                       field: "ActualFinish",
                       title: "ActualFinish",
                       format: "{0:MM/dd/yyyy}",
                       width: 120
                   },
                   {
                       field: "LastUpdatedBy",
                       title: "LastUpdatedBy",
                       width: 120
                   },
                   {
                       field: "LastUpdatedDate",
                       title: "LastUpdatedDate",
                       width: 120
                   }
               ]
           });
       });

WCF Service:

    public void UpdateIndicators(List<IndicatorGridLineItem> Indicators)

The answer came to me after working with your answer and the answer shown here: https://stackoverflow.com/a/6323528/1710400

Community
  • 1
  • 1
ComputerG33k
  • 151
  • 1
  • 2
  • 8