7

I am trying to Load list items in lazy load like Facebook. I have a grid that loads data from a list, and that list may have up to 5000 items and to load all those Items in grid it takes a lot of time so performance is key on my scenario. I could have used gridview paging but this solution was canceled as not the proper solution. Instead I have to load data when I scroll down the scroller till the last item is being loaded.

So I have the following code but I am getting this error: Failed to load resource: the server responded with a status of 500 (Internal Server Error)

<script type="text/javascript">
var pageIndex = 1;
var pageCount;
$(function () {
    //Remove the original GridView header
    $("[id$=gvCustomers] tr").eq(0).remove();
});

//Load GridView Rows when DIV is scrolled
$("#dvGrid").on("scroll", function (e) {
    var $o = $(e.currentTarget);
    if ($o[0].scrollHeight - $o.scrollTop() <= $o.outerHeight()) {
        GetRecords();

    }
});

//Function to make AJAX call to the Web Method
function GetRecords() {
    pageIndex ++;
    //if (pageIndex == 2 || pageIndex <= pageCount) 
    {

        $.ajax({
            type: "POST",
            url: "TESTLargeData.aspx/GetCustomers",
            data: '{pageIndex: ' + pageIndex + '}',
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: OnSuccess,
            failure: function (response) {
                alert(response.d);
            },
            error: function (xhr, status, error) {
                alert(error);
            }
        });
    }
}

//Function to recieve XML response append rows to GridView   
function OnSuccess(response) {
    alert('onsuces!');
    var xmlDoc = $.parseXML(response.d);
    var xml = $(xmlDoc);
    pageCount = parseInt(xml.find("PageCount").eq(0).find("PageCount").text());
    var customers = xml.find("Customers");
    $("[id$=gvCustomers] .loader").remove();
    customers.each(function () {
        var customer = $(this);
        var row = $("[id$=gvCustomers] tr").eq(0).clone(true);
        $(".Id", row).html(customer.find("Id").text());
        $(".Name", row).html(customer.find("Name").text());            
        $("[id$=gvCustomers]").append(row);
    });

    //Hide Loader
    $("#loader").hide();
}

C# code

protected void Page_Load(object sender, EventArgs e)
    {
        gvCustomers.DataSource = FetchList(30);
        gvCustomers.DataBind();

    }

    private static DataSet FetchList(int pageIndex)
    {
        using (DataSet ds = new DataSet())
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Id", typeof(string));
            dt.Columns.Add("Name", typeof(string));
            SPList lista = SPContext.Current.Web.GetList("mysite/Lists/LageData");

            SPListItemCollection items = lista.GetItems();
            for (int i = pageIndex; i < pageIndex +5; i++)
            {
                DataRow dr = dt.NewRow();
                dr["Id"] = items[i]["ID"].ToString();
                dr["Name"] = items[i]["Title"].ToString();
                dt.Rows.Add(dr);

            }
            ds.Tables.Add(dt);
            return ds;
        }                      

    }

    [WebMethod]
    public static string GetCustomers(int pageIndex)
    {            
        return FetchList(pageIndex).GetXml();
    }
  • Does it display some records on page load and error comes only when you scroll down? Can you add try catch to the FetchList method and return the catch stack trace to see what exactly is the error? – Ahmad Zia Oct 4 '17 at 23:28
  • Yes you are right, when I load the page it shows some records but when I scroll down the error pops up. I cannot trace it all I am getting is Internal Server Error – Nderon Hyseni Oct 5 '17 at 6:43
  • where you host your web service TESTLargeData.aspx/GetCustomers? – Mohamed El-Qassas MVP Oct 13 '17 at 21:18
  • @M.Qassas I have created the WebService within the same solution that I am creating the webPart – Nderon Hyseni Oct 13 '17 at 21:23
  • Did you try to create it in independent solution and try to browse it then check if you got the same issue or not? just to make sure it's related to sharepoint or web service itself?! – Mohamed El-Qassas MVP Oct 13 '17 at 21:30
4
+100

Based on the chat conversion, we have tried to trace the root cause of 500 internal server error and finally, we found out

  • the OP has used SOAP web service, so it should return XML instead of json as a datatype!

Unfortunately, he tries to return XML before but he faces another issue related to sending parameter where the parameter value always comes null!!!

After checking the code, I found the data: section in the Ajax call had some errors!

Finally, the code should be

 var webserUrl = "/_layouts/15/Load5MoreComments/CommentFetchSvc.asmx";
        var soapRequest =
'<?xml version="1.0" encoding="utf-8"?> \
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" \
xmlns:xsd="http://www.w3.org/2001/XMLSchema" \
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> \
<soap:Body> \
<ReadComments xmlns="http://tempuri.org/">\
<pagenum>4</pagenum>\
</ReadComments>\
</soap:Body> \
</soap:Envelope>';
        $.ajax({
            type: "POST",
            url: webserUrl,
            contentType: "text/xml",
            dataType: "xml",
            data: soapRequest,
            success: function (msg) {
                console.log(msg);
            },
            error: ErrorOccur
        });


        function ErrorOccur(data, status, req) {
            alert(req.responseText + " " + status);
        }

By the way, using SSOM to retrieve list items then try to Load it in lazy load is not a good solution as @Evariste said!

So I suggest using JSOM or REST API to retrieve your items based on specific criteria like showing the list item based on the created date order by Descending and increment the date variable and compare it to the created date in each scroll down event!

Check some examples at

Check also

4

First:
To really troubleshoot the very generic "500 (Internal Server Error)" error, you'd need to get access to the server ULS logs, or attach a debugger to w3wp.exe. 500 only means a basic error has occurred in your code. Could be anything, like a NullReferenceException (e.g. items[i]["Title"] is null), a FileNotFoundException (e.g. list "mysite/Lists/LageData" cannot be found because your Ajax calls a wrong URL), etc...

Second:
Anyway, your approach is probably not the correct one: you're actually loading all the items from the server-side code, and then filter-out the very few you need for the requested page. This is already a performance bottleneck as the C# code sends a SQL request to load all the 5000 items (this leads to SQL overload, network overload, w3wp memory consumption); you're only saving the (gzipped) network load between the SharePoint front server and the client: that's not the most resources-consuming part.

There's 2 possible "better" approches:

  1. Use the version of GetItems() that takes an SPQuery. Add a query that involves an OrderBy clause on ID and filter items starting at a given ID (i.e. the ID of the last item retrieved on the previous page).

    SPQuery query = new SPQuery();
    query.Query = string.Format("<Where><Gt><FieldRef Name='ID' /><Value Type='Counter'>{0}</Value></Gt></Where><OrderBy><FieldRef Name='ID' /></OrderBy>", lastDisplayedItemID);
    query.RowLimit = 15; // Assuming batches of 15 items
    SPListItemCollection items = lista.GetItems();
    

This requires the client to send the last retrieved ID when calling the Web method.

  1. Use SPListItemCollectionPosition.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.