Tips and Tricks in a world of Mix

 

Well, here’s the thing. What I needed to create was a small simple example (POC if you’d like)  of getting information from different external sources, like in Xml or Query String formats.  Requirements :

1)Write the aspx in such a way , that if tomorrow we’d add another type of external input context , I wouldn’t have to change it ( the aspx).

2)No postback aloud – we don’t want the page to render itself each time we hit the button .

__________________________________________________________________________

My solution was to do it through Ajax-Enabled Web Service . Here is the explanation , you can download the code from here.

To create the ASP.NET client application

 

1. Open Visual Studio 2010.

2. From the File menu, select New, then Project, then Web, and then select ASP.NET Web Application.

3. Name the Project FillTableFromExternal and click OK.

To create the WCF AJAX-enabled service

 

1. Right-click the FillTableFromExternal project in the Solution Explorer window and select Add, then New Item, and then AJAX-enabled WCF Service.

2. Name the service MyGetDataService.svc in the Name box and click Add.

3. Open the MyGetDataService.svc.cs file.

4. Specify the Namespace for ServiceContractAttribute as FillTableFromExternal:

namespace FillTableFromExternal
{
[ServiceContract(Namespace = "FillTableFromExternal")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class MyGetDataService
{
// Add more operations here and mark them with [OperationContract]
}
}

5. Implement the operations in the service.

-Add the OperationContract Attribute to each of the operations to indicate that they are part of the contract.

-[WebGet(ResponseFormat = WebMessageFormat.Json , BodyStyle = WebMessageBodyStyle.WrappedRequest  )]  – is defining in what format the data is returning to the caller .

The following example implements a method that returns MyData object .

MyData object is actually is a basic from of BL . Some separate component , that will be changed if we add some other logic in the future.

public class MyGetDataService
{
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json , BodyStyle = WebMessageBodyStyle.WrappedRequest  )]
public MyData  GetDataFunc(int ReturningTypeEnum)
{
return new MyData(ReturningTypeEnum);
}
}

Adding The Business Logic component

 

1. Right-click the FillTableFromExternal project in the Solution Explorer window and select Add, then New Item, and then Class.

2. Name the service MyData.cs in the Name box and click Add.

3. Build a constructor :

public MyData(int FormatType)
{
switch (FormatType)
{
case 1://Xml
GetHtml(XmlUri);
break;
case 2://QueryString
GetQueryString(QueryStringUri);
break;
default:
break;
}
}

So . in this constructor we are only switching to some logic by a parameter of a FormatType we were asked to return .

The functions are working as some basic type of providers analyzing the incoming data from predefined URI’s .

4.The predefined URI’s  will be defined as private member in the class and added as keys to the web.config – in the future , if the external service will change its location all you’ll need is to adjust a web.config , without any recompilation of the whole together application and the drag of the republishing an so on .

Private member in the class :

private string XmlUri = ConfigurationManager.AppSettings.Get("XmlUri");
private string QueryStringUri = ConfigurationManager.AppSettings.Get("QueryStringUri");

The web.config addition :

<appSettings >
<add  key ="XmlUri" value ="http://localhost:65304/ExternalXml.aspx"/&gt;
<add key ="QueryStringUri"  value ="http://localhost:65304/ExternalQueryString.aspx&quot; />
</appSettings>

(as you can see I’ve created the externals inside my project , but in real life you’ll get it from third party).

5. Add some container to carry your data. In my case I’ll have a structure of two fields only  – ( transaction id and status )  , so I’ve chosen the Dictionary and declared it as property :

public Dictionary<string, string> rows { get; set; }

6. Get and Analyze an Xml from predefined url :

private void GetXML(string url)
{
rows = new Dictionary<string, string>();
HttpWebRequest myWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
myWebRequest.Method = "GET";
// make request for web page
HttpWebResponse myWebResponse =(HttpWebResponse)myWebRequest.GetResponse();
StreamReader myWebSource = new StreamReader(myWebResponse.GetResponseStream());

string myPageSource = string.Empty;
myPageSource= myWebSource.ReadToEnd();
myWebResponse.Close();
XmlDocument xd = new XmlDocument();
xd.LoadXml(myPageSource);
XmlNodeList xnl = xd.SelectNodes("//new");
foreach (XmlNode el in xnl)
{
string tran = el.SelectSingleNode("transaction").InnerText;
string status = el.SelectSingleNode("status").InnerText;

rows.Add(tran, status);

}

}

Through all the first part of the code we are getting the Xml into myPageSource and than we are analyzing the content to get each child into temporary parameters tran and status , afterwards we are adding it to the rows. Pay attention – I’ve initialized it at the beginning of the function. It’s a property and nothing is needed to be returned.

This ends the Initializing of the MyData Object for Xml Format.

7. Get and Analyze an Query String from predefined Url :

Same logic  , different libraries :

private void GetQueryString(string url)
{
rows = new Dictionary<string, string>();
HttpWebRequest myWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
myWebRequest.Method = "GET";
// make request for web page
HttpWebResponse myWebResponse = (HttpWebResponse)myWebRequest.GetResponse();
string tran = System.Web.HttpUtility.ParseQueryString(myWebResponse.ResponseUri.ToString())[0];
string status = System.Web.HttpUtility.ParseQueryString(myWebResponse.ResponseUri.ToString())["status"];
rows.Add(tran, status);
myWebResponse.Close();

}
Here we’re ParseQueryString the myWebResponse  , entering the data into temporary parameters and adding it to our dictionary property .

This ends the Initializing of the MyData Object for Query String Format.

Creating Xml output from ASPX

 

Well , I didn’t have an Xml External Source , so I’ve created one :

1. Right-click the FillTableFromExternal project in the Solution Explorer window and select Add, then New Item, and then WebForm.

2. Name the service ExternalXml.aspx in the Name box and click Add.

3. Delete the files  :  ExternalXml.aspx.cs and ExternalXml.aspx.designer.cs

4. Copy and paste to aspx file :

<%@ Import Namespace="System.Xml" %>
<%@ Import Namespace="System.Text" %>
<script language="C#" runat="server">

void Page_Load(object sender, EventArgs e)
{
// Create a new XmlTextWriter instance
XmlTextWriter writer = new
XmlTextWriter(Response.OutputStream, Encoding.UTF8);
// start writing!
writer.WriteStartDocument();
writer.WriteStartElement("root");
writer.WriteStartElement("new");
// Creating the <first child> element
writer.WriteElementString("transaction", "1");
writer.WriteElementString("status", "Decline");
writer.WriteEndElement();
writer.WriteStartElement("new");
// Creating the <second child> element
writer.WriteElementString("transaction", "2");
writer.WriteElementString("status", "Accept");
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Close();
}
</script>
Response.OutputStream will stream the xml to the caller by url.

So if we’ll address the url ( right-click the ExternalXml.aspx –> View in Browser ) we’ll get :

<?xml version="1.0" encoding="utf-8" ?>
<root>
<new>
<transaction>1</transaction>
<status>Decline</status>
</new>
<new>
<transaction>2</transaction>
<status>Accept</status>
</new>
</root>

This is our data , that will be analyzed in GetXML function.

Creating QueryString output from ASPX

 

1. Right-click the FillTableFromExternal project in the Solution Explorer window and select Add, then New Item, and then WebForm.

2. Name the service ExternalQueryString.aspx in the Name box and click Add.

3. Enter the ExternalQueryString.aspx.cs and add to the Page_Load the query string creation (automatically when called the page will redirect with some parameters (hardcoded just for example in our case) in the url:

private void Page_Load(object sender, System.EventArgs e)
{
string url = "Default.aspx?";
url += "transaction=" + "10" + "&";
url += "status=" + "QueryStatus1" ;
Response.Redirect(url);
}

Lets check it out : ( right-click the ExternalQueryString.aspx –> View in Browser  ) …

What the heck are we getting – we are at our front page ?! That must be wrong..

clip_image002[1]

So the point is that I want to redirect to some existing page , and I know that my front page will be alive , because we ar coming from there , so the only thing that we are interested in here is the address string  after the ? sign .

clip_image004[1]

This is our data , that will be analyzed in GetQueryString function.

Configure the client to access the WCF service

 

1. Open the Default.aspx page and select the Design view.

2. From the View menu, select Toolbox.

3. Expand the AJAX Extensions node and drag and drop a ScriptManager on to the Default.aspx page.

4. Right-click the ScriptManager and select Properties.

5. Expand the Services collection in the Properties window to open up the ServiceReference Collection Editor window.

6. Click Add, specify MyGetDataService.svc as the Path referenced, and click OK.

(be advised , if the svc is in your project you better add it as relational path – ~/MyGetDataService.svc  , otherwise it may not find your service)

7. Expand the HTML node in the Toolbox and drag and drop an Input (Text) on to the Default.aspx page.

8. Expand the HTML node in the Toolbox and drag and drop an Input (Button) on to the Default.aspx page.

9. Right-click the Button and select Properties.

10. Change the Value field to Show Data.

11. Double-click the Button to access the JavaScript code.

12. Pass in the following JavaScript code within the <script> element.

<script language="javascript" type="text/javascript">
// <![CDATA[
function Button1_onclick() {
var service = new FillTableFromExternal.MyGetDataService();
service.GetDataFunc(parseInt($("#Text1").val()), onSuccess, null, null);
}
function onSuccess(result) {
buildTable(result.rows);
}
function buildTable(tableData) {
var table = $("#grid");
table.html("");  //clear out the table if it was previously populated
table.append(‘<thead><tr></tr></thead>’);
var thead = $(‘thead tr’, table);
//create the table headers
thead.append(‘<th>Transaction ID </th>’);
thead.append(‘<th>Status</th>’);
//add the table rows
$(tableData).each(function (key, val) {
table.append(‘<tr></tr>’);
var tr = $(‘tr:last’, table);
tr.append(‘<td>’ + this.Key + ‘</td>’);
tr.append(‘<td>’ + this.Value + ‘</td>’);
});
}
// ]]>
</script>

In Button1_onclick we are accessing our service as has been defined in the ScriptManager –

you can see the reference at :

<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="~/MyGetDataService.svc" />
</Services>
</asp:ScriptManager>

Once the client recognized your Service you’ll have full intelisence for it.

We are accessing the GetDataFunc ,that we’ve written at the very beginning, passing the value of the textbox , using jquery syntax , we’ve added to the page.

buildTable(tableData) – will dynamically build a table using the property of the object  MyData named rows . So from result that we get we are passing the rows property value to the building function  -  buildTable(result.rows);

13. Add some div with table in it to the source code of the aspx :

<div class="centered" >
<table id="grid" ></table>
</div>

I’ve already added the class to the div .

This way our table will be at the middle of the page.

Another thing is the grid id of the table – this is the identifier in which we are building the table in the buildTable function  – ("#grid")

14. Let’s add some styling – go to Styles folder , and double-click Site.css.

15. Add to the file :

div.centered
{
text-align: center;
}
div.centered table
{
margin: 0 auto;
text-align: left;
}

16.Double-click Scripts folder.

17.Double-click Site.Master

18.Drug and Drop the files into the header of the master – this will allow us to use the JQuery in the web site

<head runat="server">
<script src="Scripts/jquery-1.4.1-vsdoc.js" type="text/javascript"></script>
<script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script>
you may do it relative..

That’s about it.

We are pressing F5 –

When we’ll enter 1 and press show data – we’ll get the Xml format to the client.

clip_image006[1]

When we’ll enter 2 and press show data – we’ll get the Query String format to the client.

clip_image008[1]

Summary

 

We used Ajax-Enabled WCF service to get different sorts of input data source .

1) There is no PostBack in our code.

2) When we’ll need to add another type of data – Data Services  or RIA Services or some not invented yet services , we will only adjust the MyData.cs part. I’ve made the handling of the formats in functions , but you can export it to a separated provider component if needed.

3) We are working with JQuery , which is always more fun and quick .

4) Added some styling just for the kicks of it.

You can download the sample code from here

 

So , if you liked it and used it , say thanks in comments.

Cheers!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Tag Cloud

%d bloggers like this: