简体   繁体   中英

Trying to bind data from SQL Server using a C# web method(ASP .NET) to a grid coded using jQuery

I hope the title of my question is descriptive and helpful for you to understand the issue that I am facing. I am new to programming, and I am aware that the issue I am facing is something that only a beginner would have issues with. Please do help me out. Please bear with me as this is quite a long description. I am aware that most of you who are a part of this community are very experienced programmers and wouldn't require such detailed methodology but it isn't my intention to waste your time and I believe that by giving such a detailed description, you would be able to help me better. Now about the issue, I am trying to build a grid using jQuery:

https://www.jqwidgets.com/jquery-widgets-demo/demos/jqxgrid/index.htm#demos/jqxgrid/defaultfunctionality.htm

I have used the source code from the link above to build the gird, but when I run the program, the data doesn't get displayed. I am sure that the issue lies in the jQuery because I have run my web service separately and it connects to SQL Server and displays the output in the form of a JSON array.

I have broken the solution into three projects on Visual Studio 2019:

  1. PracticeValidation project - contains 3.aspx c# web forms. One for the homepage, another for the recipe form and a third for the employee form.
  2. WebServicesFunctionality project - Contains one.asmx Webservice file which holds 2 web methods(one for the recipe form, the other for the employee form) to serialise the data coming in the form of a list into a JSON array. Please find the code for the web service attached below.
[System.Web.Script.Services.ScriptService]
    public class WebService1 : System.Web.Services.WebService
    {

        [WebMethod]
        public string GetRecipe()
        {
            JavaScriptSerializer js = new JavaScriptSerializer();
            string recipeList = String.Empty;
            List<FormGeneratorClass.FormGeneratorVar.RecipeVar> recipeCatcher = new List<FormGeneratorClass.FormGeneratorVar.RecipeVar>();
            recipeCatcher = FormGeneratorClass.FormGeneratorVar.ExecuteRecipeList();
            if (recipeCatcher != null && recipeCatcher.Count > 0)
            {
                recipeList = js.Serialize(recipeCatcher);
            }
            else
                recipeList = js.Serialize("No recipes!");
            return recipeList;
        }

        [WebMethod]
        public string GetEmp()
        {
            JavaScriptSerializer js = new JavaScriptSerializer();
            string EmployeeList = String.Empty;
            List<FormGeneratorClass.FormGeneratorVar.EmpVar> employeeCatcher = new List<FormGeneratorClass.FormGeneratorVar.EmpVar>();
            employeeCatcher = FormGeneratorClass.FormGeneratorVar.ExecuteEmployeeList();
            if (employeeCatcher != null && employeeCatcher.Count > 0)
            {
                EmployeeList = js.Serialize(employeeCatcher);
            }
            else
                EmployeeList = js.Serialize("No recipes!");
            return EmployeeList;
        }
    }
  1. FormGeneratorClass project: This project holds a c# class file which is responsible for interacting with SQL Server. I am attaching the code inside this file below.
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FormGeneratorClass
{
    public class FormGeneratorVar
    {
        public class RecipeVar
        {
            public int Recipe_Id { get; set; }
            public string Recipe_Name { get; set; }
        }

        public class EmpVar
        {
            public int Emp_Id { get; set; }
            public string Emp_FirstName { get; set; }
            public string Emp_LastName { get; set; }
        }

        public static List<RecipeVar> ExecuteRecipeList()
        {
            List<RecipeVar> listRecipe = new List<RecipeVar>();
            string strConnString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
            using (SqlConnection con = new SqlConnection(strConnString))
            {
                string sqlSelectAllQuery = "SELECT * FROM Tbl_Recipe";
                SqlCommand cmd = new SqlCommand(sqlSelectAllQuery, con);
                con.Open();
                SqlDataReader rdr = cmd.ExecuteReader();
                while (rdr.Read())
                {
                    RecipeVar recipe = new RecipeVar();
                    recipe.Recipe_Id = !(rdr["recipe_id"] == DBNull.Value) ? Convert.ToInt32(rdr["recipe_id"]) : 0;
                    recipe.Recipe_Name = !(rdr["recipe_name"] == DBNull.Value) ? Convert.ToString(rdr["recipe_name"]) : string.Empty;
                    listRecipe.Add(recipe);
                }
                con.Close();
            }
            return listRecipe;
        }

        public static List<EmpVar> ExecuteEmployeeList()
        {
            List<EmpVar> listEmployee = new List<EmpVar>();
            string strConnString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
            using (SqlConnection con = new SqlConnection(strConnString))
            {
                string sqlSelectAllQuery = "SELECT * FROM Tbl_Emp";
                SqlCommand cmd = new SqlCommand(sqlSelectAllQuery, con);
                con.Open();
                SqlDataReader rdr = cmd.ExecuteReader();
                while (rdr.Read())
                {
                    EmpVar employee = new EmpVar();
                    employee.Emp_Id = !(rdr["emp_id"] == DBNull.Value) ? Convert.ToInt32(rdr["emp_id"]) : 0;
                    employee.Emp_FirstName = !(rdr["emp_firstName"] == DBNull.Value) ? Convert.ToString(rdr["emp_firstName"]) : string.Empty;
                    employee.Emp_LastName = !(rdr["emp_lastName"] == DBNull.Value) ? Convert.ToString(rdr["emp_lastName"]) : string.Empty;
                    listEmployee.Add(employee);
                }
                con.Close();
            }
            return listEmployee;
        }
    }
}

I will set the WebServicesFunctionality project(pt.2) as the startup project and take a screenshot of the result I get for your reference

  1. The web service is loaded on my local browser

  2. The output after the employee web method gets invoked

  3. The output after the recipe web method gets invoked

Now I'm sure all those reading this post will have a clearer idea about what I'm trying to do. So now I'll attach the code for employee.aspx page.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="EmployeeRecord.aspx.cs" Inherits="PracticeValidation.WebForm2" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Record of employees</title>
    <meta name="description" content="JavaScript Grid with rich support for Data Filtering, Paging, Editing, Sorting and Grouping" />
    <link href="Scripts/jqx.base.css" rel="stylesheet" type="text/css"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width, initial-scale=1 maximum-scale=1 minimum-scale=1" />
    <script src="Scripts/jquery-1.11.1.min.js"></script>
    <script src="Scripts/jqxcore.js"></script>
    <script src="Scripts/jqxdata.js"></script>
    <script src="Scripts/jqxbuttons.js"></script>
    <script src="Scripts/jqxscrollbar.js"></script>
    <script src="Scripts/Menu.js"></script>
    <script src="Scripts/jqxcheckbox.js"></script>
    <script src="Scripts/jqxlistbox.js"></script>
    <script src="Scripts/jqxdropdownlist.js"></script>
    <script src="Scripts/jqxgrid.js"></script>
    <script src="Scripts/jqxgrid.sort.js"></script>
    <script src="Scripts/jqxgrid.pager.js"></script>
    <script src="Scripts/jqxgrid.selection.js"></script>
    <script src="Scripts/jqxgrid.edit.js"></script>
    <script src="Scripts/demos.js"></script>
    <script type="text/javascript">
            $(document).ready(function () {
                //Getting the source data with ajax GET request
                source = {
                    datatype: "json",
                    datafields: [
                        { name: 'EmpID' },
                        { name: 'EmpLastName' },
                        { name: 'EmpFirstName' }
                    ],
                    async: false,
                    record: 'Table',
                    url: 'WebService1.asmx/GetEmp',

                };
                var dataAdapter = new $.jqx.dataAdapter(source,
                    { contentType: 'application/json; charset=utf-8' }
                );
                $("#grid").jqxGrid({
                    source: dataAdapter,
                    theme: 'classic',
                    width: '100%',

                    columns: [
                        { text: 'EmpID', dataField: 'EmpID', width: 250, hidden: false },
                        { text: 'EmpLastName', dataField: 'EmpLastName', width: 150 },
                        { text: 'EmpFirstName', dataField: 'EmpFirstName', width: 180 },
                    ]
                });
            });
    </script>
</head>
<body class ='default'>
    <form id="form1" runat="server">
        <div>
            <h1>Welcome to the record of employees page</h1>
            <h4>Click <a href="HomePage.aspx">here</a> to go back to the main login page</h4>
        </div>
        <div id="grid">
        </div>
    </form>
</body>
</html>

I will finally attach the screenshot of the output that I get.

Output of the employee record.aspx page: 在此处输入图像描述

Thank you to all those who have read the whole post and stay safe!

I figured out where I was going wrong. There were a lot of reasons why the data wasn't getting bound to the grid the way I wanted. I hope this is helpful for anybody else with the same issue.

The first problem you need to solve if you're creating a solution the way I did is that you need to create a proxy web service that gets the data from the web service. This is because, the web service project and the web form project run on a different port. So, even if everything is right, you would get a 404 error when making an AJAX request. So create a web service proxy from the web form project or else just ditch the idea of creating a separate web service project.

The next problem I ran into was a doozy and took me a really long time to figure out. Irrespective of serializing the data coming from SQL into JSON, the data that actually gets sent back from the web service is XML. This is because web services use SOAP and hence by default the method of data transfer is XML. If you run your web service and observe the data, you will see a JSON string with an XML wrapper. If you open Chrome dev tools and look at the content-type, you would see that its returning XML and no matter what you do, you cannot stop a web service from returning XML through an AJAX 'GET' request. So how do you solve the problem? Two ways:

Method 1: Use a Web API instead of a Web service. This will allow you to use REST services.

Method 2: If you're adamant about using a web service, then the following link will be super helpful. https://www.one-tab.com/page/IjhbYbayRlWka-8ruNI87w

After I got my AJAX returning JSON from a web service successfully. The next issue was getting the data bound to the grid plug in. This is pretty simple and straightforward. Find the demo of the method you want to use and copy paste the entire thing into the success call back function of the AJAX request. You could even pass the data you are receiving by calling a user defined function INSIDE the success call back function of the AJAX request.

Sometimes you might run into an issue when consuming a web service using an AJAX request which says that "there was an error during the serializing or deserializing. Maximum JSON length property exceeded". If you do face this try initializing the javascriptSerializer object to a maxInt value.

If you are using Newtonsoft.JSON, then please check to see if your data gets serialized using the regular javascriptSerializer class. The reason why I say this is because AJAX requests serialize data using javascriptSerializer and Newtonsoft.JSON tends to overlook circular reference errors. As a result, the Ajax function might throw a "there was an error during serializing or deserializing. Maximum JSON length property exceeded" error when in actuality your web service is running into a circular reference error. Consider making changes to the SP or query that you are using if this is the case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM