PDA

View Full Version : How to call ASP WebService from ExtJS?



Goldcoding
10 May 2010, 5:52 AM
Hello, Guys
Please, help me with next problem. I have a webservice which returns array of teams. Where team is a class which discribes a football team with three attributes: Team Id, Team Name and Team country. The question is next: how to call my webservice from ExtJs script and parse recived array in variable myData (file WebApp.js)?

ASP Code Index.aspx, start page of project:


<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="TestProject.Index" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Test Project</title>

<%-- Include Ext Js libraries --%>
<link href="ExtJsCore/resources/css/ext-all.css" type="text/css" rel="stylesheet">
<script type="text/javascript" src="ExtJsCore/adapter/ext/ext-base.js"> </script>
<script type="text/javascript" src="ExtJsCore/ext-all.js"> </script>

<%-- Include my ExtJs script which shows grid --%>
<script type="text/javascript" src="WebAppCore/WebApp.js"> </script>
</head>

<body>
<%-- Include my WebSerive to asp page--%>
<div>
<form id="Form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="WebService1.asmx" />
</Services>
</asp:ScriptManager>
</form>
</div>

<%-- Show grid through div tag --%>
<div id="grid-example">

</div>
</body>
</html>
WebService1.asmx.cs, my general webservice with two methods: HelloWorld() and GetAllTeams()


using System;
using System.Collections;
using System.Linq;
using System.Web;
using System.Web.Services;


namespace TestProject
{
/// <summary>
/// Summary description for WebService1
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]
public class WebService1 : System.Web.Services.WebService
{

[WebMethod]
public string HelloWorld()
{
return "Hello World";
}

//This method return arrays of objects Team
[WebMethod]
public ArrayList GetAllTeams()
{
ArrayList AllTeams = new ArrayList();

AllTeams.Add(new Team(1,"MyTeam1", "Ukraine"));
AllTeams.Add(new Team (2, "MyTeam2", "USA"));

return AllTeams;
}
}

//It is my own class where I describe class Team whcuh have three attributes: TeamId, TeamName and TeamCountry
public class Team
{
int TeamId;
string TeamName;
string TeamCountry;

public Team() { }
public Team(int ID, string Name, string Country)
{
this.TeamId = ID;
this.TeamName = Name;
this.TeamCountry = Country;
}
}
}
Ext JS file, WebApp.js:


Ext.onReady(function () {

Ext.state.Manager.setProvider(new Ext.state.CookieProvider());

// data which currently populate grid.
var myData = [
[1, 'Metallist Kharkiv', 'Ukraine'],
[2, 'Shakhtar Donetsk', 'Ukraine'],
[3, 'Chelsea London', 'UK']
];

// create the data store
var store = new Ext.data.ArrayStore({
fields: [
{ name: 'id', type: Ext.data.Types.INT },
{ name: 'name'},
{ name: 'country'}
]
});

//load local data
store.loadData(myData);

// create the Grid
var grid = new Ext.grid.GridPanel({
store: store,
columns: [
{ id: 'id', header: 'Team Id', width: 160, sortable: true, dataIndex: 'id' },
{ header: 'Team Name', width: 75, sortable: true, dataIndex: 'name' },
{ header: 'Team Country', width: 75, sortable: true, dataIndex: 'country' },
],
stripeRows: true,
autoExpandColumn: 'id',
height: 300,
width: 500,
title: 'Array Grid',
// config options for stateful behavior
stateful: true,
stateId: 'grid'
});

// render the grid to the specified div in the page
grid.render('grid-example');
});

Goldcoding
10 May 2010, 7:29 AM
I have found answer: :)

Class Team(defined in webservice):


public class Team
{
public int TeamId;
public string TeamName;
public string TeamCountry;

public Team() { }
public Team(int ID, string Name, string Country)
{
this.TeamId = ID;
this.TeamName = Name;
this.TeamCountry = Country;
}
}
Webservice method:


//This method return arrays of objects Teams
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json,
UseHttpGet = true, XmlSerializeString = false)]
public List<Team> GetAllTeams()
{
List<Team> AllTeams = new List<Team>();
AllTeams.Add(new Team (1,"MyTeam1", "Ukraine"));
AllTeams.Add(new Team (2, "MyTeam2", "USA"));
return AllTeams;
}
and

ExtJs variable myStore:


// Create store
var myStore = new Ext.data.JsonStore({
// Load data at once
autoLoad: true,
// Override default http proxy settings
proxy: new Ext.data.HttpProxy({
// Call web service method using GET syntax
url: 'WebService1.asmx/GetAllTeams',
// Ask for Json response
headers: {'Content-type': 'application/json'}
}),
// Root variable
root: 'd',
// Record identifier
id: 'TeamId',
// Fields declaration
fields: ['TeamId', 'TeamName', 'TeamCountry']
});


Think somebody find it usefull )

TonyBones
8 Jul 2010, 11:04 AM
I'm doing something similar to this but its not working. I'm returning a String instead of a List of objects. But my string is already a correct json string.

And my grid is being populated with 132 blank empty rows, even though the json data i'm returning from the service webmethod only contains 2 rows of data.

json response string


{"d":"[{id: 1, name: \u0027First Name\u0027, email: \[email protected]\u0027, salary: 100},{id: 2, name: \u0027Second Name\u0027, email: \[email protected]\u0027, salary: 200}]"}

mankz
8 Jul 2010, 11:39 AM
@TonyBones: Have you set the root in your store to 'd'?

TonyBones
8 Jul 2010, 1:47 PM
I have set root to 'd', yes.

TonyBones
8 Jul 2010, 2:50 PM
So i changed from returning a plain old string to using a list of objects like above and now its working. Only difference i see is with how it escaped my single quotes in the first json string i posted.



{"d":[{"id":1,"name":"Anthony","email":"[email protected]"},{"id":2,"name":"Lindsay","email":"[email protected]"}]}
So the question is now, where do I put the data needed to do server side paging and sorting in this json? The Ext docs show a different json structure using 'total' and a root object deeper in the structure. Why does this stuff get wrapped in a 'd' tag?

From Example:


{
results: 2000, // Reader's configured totalProperty (http://www.sencha.com/deploy/dev/docs/output/Ext.data.JsonReader.html#Ext.data.JsonReader-totalProperty)
rows: [ // Reader's configured root (http://www.sencha.com/deploy/dev/docs/output/Ext.data.JsonReader.html#Ext.data.JsonReader-root)
// record data objects:
{ id (http://www.sencha.com/deploy/dev/docs/output/Ext.data.JsonReader.html#Ext.data.JsonReader-idProperty): 1, firstname: 'Bill', occupation: 'Gardener' },
{ id (http://www.sencha.com/deploy/dev/docs/output/Ext.data.JsonReader.html#Ext.data.JsonReader-idProperty): 2, firstname: 'Ben' , occupation: 'Horticulturalist' },
...
]
}Won't that entire thing get wrapped in 'd'? then what do I use as my root field?

mankz
8 Jul 2010, 9:16 PM
The 'd' is MS trying to protect you from JSON hijacking, read more here:http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx

Your new root should be "d.rows".

TonyBones
9 Jul 2010, 1:57 PM
cool. I actually had d.rows in there at first back when i was returning the json string which was being encoded as a string instead of an object. so yea, its working great now! Thanks so much for the info.