Search code examples
javascriptjqueryjsonc#-4.0webmethod

Pass json array to WebMethod


I'm trying to pass a object to json array as string but I got Internal Server Error.

The method GetServerTime is working.

I want to pass array of objects to server and convert it to a generic list of ProcessDetail

public class ProcessDetail
{
    public DateTime? StartDate {get;set;}
    public DateTime? EndDate {get;set;}
}

//Web Methods
[WebMethod]
public static string GetServerTime()
{
    return DateTimeHelper.AppDateTime.ToString(CultureInfo.CurrentCulture);
}

[WebMethod]
public static string GetDurations(string text)
{
    List<ProcessDetail> details = DeSerialize<ProcessDetail>(text);
    return string.Empty;
}

public static List<T> DeSerialize<T>(string input)
{
    var serializer = new DataContractJsonSerializer(typeof(List<T>));

    using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(input)))
    {
        return (List<T>)serializer.ReadObject(ms);
    }
}

// Javascirpt
<script>
    function DateChanged() {
        var grid = document.getElementById('<%= gvProcessMonitoring.ClientID %>');
        var servertime = getData('<%= ResolveUrl("ViewCharts.aspx/GetServerTime") %>', {});
        alert(servertime);

        var processDetails = {
            processDetail: []
        };

        if (grid.rows.length > 0) {
            for (var i = 1; i < grid.rows.length; i++) {
                var txtStartDate = grid.rows[i].getElementsByClassName('grdtxtStartDate')[0];
                var txtEndDate = grid.rows[i].getElementsByClassName('grdtxtEndDate')[0];

                processDetails.processDetail.push({
                    "StartDate": "'" + txtStartDate.value + "'",
                    "EndDate": "'" + txtEndDate.value + "'"
                });
            }

            // This is giving internal server error.I have tried without stringify.
            var serverData = getData('<%= ResolveUrl("ViewCharts.aspx/GetDurations") %>', JSON.stringify(processDetails));
        }
    }

    function getData(dataUrl, dataString) {
        var jsonObject;

        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: dataUrl,
            data: dataString,
            async: false,
            cache: false,
            timeout: 30000,
            success: function (data) {
                $(".loadingdiv").remove();
                jsonObject = data.d;
            },
            error: function (result) {
                debugger;
                $(".loadingdiv").remove();
                alert("Unexpected error");
            }
        });

        return jsonObject;
    }
</script>

Solution

  • First, you don't need a processDetails object, you can simply add your objects to an array:

    var processDetails = [];
    
    for (var i = 1; i < grid.rows.length; i++) {
        // [...]
        var processDetail = { StartDate: txtStartDate.value, EndDate: txtEndDate.value };
        processDetails.push(processDetail);
    }
    

    Then, pass to getData the array not stringified:

    var serverData = getData('<%= ResolveUrl("ViewCharts.aspx/GetDurations") %>', processDetails);
    

    Some changes to do in getData:

    • Set the dataType to json
    • stringify your data

      dataType: "json",
      data: JSON.stringify({ processDetails: dataString })
      

    Some changes in ViewCharts:

    • Set your parameter text as a List<ProcessDetail>

      public static string GetDurations(List<ProcessDetail> processDetails)
      

    You can then access directly your ProcessDetail objects in your List:

    foreach (ProcessDetail processDetail in processDetails)
    {
        // processDetail.StartDate
        // processDetail.EndDate
    }