Posting data from a web service to a web page

Writing and consuming web services is one of the important things we do at work. Systems running a variety of operating systems and with a completely different set of configurations make it difficult to exchange data easily. Things get even worse when there is a difference in time zones. We really didn’t want to wait for our integration partner to come back to us with a feedback whether they received the data or not. We rather decided to take ‘just-try-it” approach to post (HTTP-POST) web service data to a web page on localhost and it worked. I know it is not a rocket science, but it saved me time and effort, so I thought of sharing it.

So, this is what we do to send data to a web service:



Try

stream = File.OpenText( "C:\ServiceData.xml" )
strXML = stream.ReadToEnd()
stream.Close()

webreq = HttpWebRequest.Create("{Web-Service-Uri}")
webreq.Method = "POST"
webreq.ContentType = "application/x-www-form-urlencoded"

strXML = "data=" & HttpUtility.UrlEncode(strXML)
bytes = System.Text.Encoding.UTF8.GetBytes(strXML)
webreq.ContentLength = bytes.Length

requestStream = webreq.GetRequestStream()
requestStream.Write(bytes, 0, bytes.Length)
requestStream.Close()

webResponse = webreq.GetResponse()
responseStream = New IO.StreamReader(webResponse.GetResponseStream())
responseStream.Close()
webResponse.Close()
webreq = Nothing

Catch ex As System.Net.WebException

Dim responseFromServer As [String] = ex.Message.ToString() & " "
If ex.Response IsNot Nothing Then
Using response As Net.WebResponse = ex.Response
Dim data As Stream = response.GetResponseStream()
Using reader As New StreamReader(data)
responseFromServer += reader.ReadToEnd()
End Using
End Udsing
End If
End Try

The above code works fine if you want to send data to a web service. However, to send to a webpage all we have to do is replace the service uri {Web-Service-Uri} on line 07 with web page address, something like this:


webreq = HttpWebRequest.Create("{Web-Service-Uri}") –> Posting to a web service


webreq = HttpWebRequest.Create("http://localhost:1886/service-data-receiver.aspx" ) –> Posting to a web page

The part which I had to figure out was how to access the data sent from a web service to my page. Since the request was not originated by a page-based model, I couldn't use Request.Forms or Request.QueryString. After some research I found that it is just Request object that can be used to access data. Yes, that is it.



Protected Sub Page_Load(ByVal sender As Object , ByVal e As System.EventArgs) Handles Me.Load

Dim response1 As String = HttpUtility.UrlDecode(Request( "data"))Dim doc As XDocument = XDocument.Parse(response1)
doc.Save( "C:\inetpub\wwwroot\service-data-received.xml" )
Response.Write(response1)

End Sub

HTH,

LINQ to XML ― brings new reasons to use more XML

I recently did a small talk about the benefits of using new XML API “LINQ to XML”. According to MSDN:

LINQ to XML provides an in-memory XML programming interface that leverages the .NET Language-Integrated Query (LINQ) Framework. LINQ to XML uses the latest .NET Framework language capabilities and is comparable to an updated, redesigned Document Object Model (DOM) XML programming interface.
The talk wealso requirednt very well, and luckily I managed to get the attention of the audience, because the approach I adopted was a little different than the normal. Instead of talking plainly about the new functions and properties, I rather tried to draw a comparison between the way we deal with the XML using existing and new API. I also shared why VB developers are more excited about this API than C# guys, and what is making them feel more privileged.

The core functionality of the new API revolves around 3 key concepts.

  1. Functional Construction
  2. Context-Free XML creation
  3. Simplified NameSpaces

Functional Construction:

The ability to create the entire XML tree or part of it by just using one statement. If you are someone like me who doesn’t play with XML day-in and day-out, you have to probably recall for a second how do you create XML and using which API. This is so true because the depth and breadth of XML API choices available to us today is overwhelming. For example,

  • XMLTextReader: for low-level parsing of XML documents.
  • XMLTextWriter: fast, non-cached, forward-only way of generating XML
  • XMLReader: read-only, forward-only API generally used to deal with large XML documents.
  • XMLDocument, XMLNode and XPathNavigator etc. etc.

So, if I want to create the below book XML in my application, I can either use XmlTextWriter.WriteStartElement() or I can also use XMLDocument.CreateNode() If document manipulation is also required.



<books>

<book>

<title>Essential .NET</title>

<author>Don Box</author>


<author>Chris Sells</author>

<publisher>Addison-Wesley</publisher>

</book>

</books>

Though, there is nothing wrong with both of the approaches mentioned above except the fact that they take more lines of code and more time as well just to churn out a tiny piece of XML. LINQ to XML aims to solve this problem by introducing XElement which takes params array as a parameter in one of its constructors allowing us to write entire XML tree in one statement.



XElement elements = new XElement("books",

new XElement("book",
new XElement("title", "Essential .NET"),
new XElement("author", "Don Box"),
new XElement("author", "Chris Sells"),
new XElement-W("publisher", "Addisonesley")
)
);

Context-Free XML creation:

When creating XML using DOM, everything has to be in context of parent document. This document-centric approach for creating XML results in code hard to read, write and debug. In LINQ to XML, attributes have been given first-class status. So, rather than going through factory methods to create elements and attributes, we can use compositional constructors offered by XElement and XAttribute class.

If I want to add an ISBN number as an attribute to the book element in the above book XML, I can simply write:



XElement elements = new XElement("books",
new XElement("book", new XAttribute(“ISBN”, “0201734117”),
new XElement("title", "Essential .NET"),
new XElement("author", "Don Box"),
new XElement("author", "Chris Sells"),
new XElement("publisher", "Addison-Wesley")
)
);

Simplified Namespaces:

I believe this is the most confusing aspect of XML. With the existing set of API, we have to remember many things like XML names, NameSpaces, prefixes associated with the NameSpaces, Namespace managers etc. LINQ to XML allows us to forget everything else and just focus on one thing called “fully expanded name” which is represented by XName class.

Let’s see how this new functionality differs from the existing one by taking an example of RSS feed of my blog. In the RSS document, which can be accessed from here http://feeds.feedburner.com/feed-irfan (right click → view source), I am interested in “totalResults” element which is prefixed by “openSearch”. This is how I do it using XMLNameSpaceManager which has been part of the .NET framework for a long time.



XmlDocument rss = new XmlDocument();

rss.Load("http://feeds.feedburner.com/feed-irfan");

XmlNamespaceManager nsManager = new XmlNamespaceManager(rss.NameTable);

nsManager.AddNamespace("openSearch", "http://a9.com/-/spec/opensearchrss/1.0/");

XmlNodeList list = rss.SelectNodes("//openSearch:totalResults", nsManager);

foreach (XmlNode node in list)
{
Console.WriteLine(node.InnerXml);
Console.ReadLine();
}


You can see I have to create XMLNameSpaceManager, add a namespace, remember the syntax of the query, provide the manager as a parameter…huh...too much of work. LINQ to XML says, forget about XMLNameSpaceManager, and create a fully expanded name and use it every time.



XElement rss = XElement.Load("http://feeds.feedburner.com/feed-irfan");

XNamespace ns = "http://a9.com/-/spec/opensearchrss/1.0/";

IEnumerable<XElement> items = rss.Descendants(ns + "totalResults");

foreach (XElement element in items)
{
Console.WriteLine(element.Value);
Console.ReadLine();
}

We can also take a look at how exactly we can load, create and update XML using LINQ to XML API.

Loading XML


  • Loading from URL:
    XElement feed = XElement.Load("http://feeds.feedburner.com/feed-irfan");

  • Loading from file:
    XElement file = XElement.Load(@"book.xml");

  • Loading from String:
    XElement document = XElement.Parse("<books><book><title>Essential.NET</title><author>Don Box</author><author>Chris Sells</author><publisher>Addison-Wesley</publisher></book></books>");

  • Loading from a reader:
    using (XmlReader xReader = XmlReader.Create(@"book.xml"))
    {
    while (xReader.Read())
    {
    if (xReader.NodeType == XmlNodeType.Element)
    break;
    }
    XElement messages = (XElement)XNode.ReadFrom(xReader);
    Console.WriteLine(messages);
    Console.ReadLine();
    }

  • XDocument:
    You may wonder If for every kind of load we use XElement, what is then the purpose of XDocument then? XDocument can be used whenever we require additional details about the document e.g. document type definition(DTD), document declaration etc. These are details which XElement doesn’t seem to provide.

Creating XML

Functional construction key concept that I mentioned above, defines the way XML is created using LINQ to XML. We have also seen above how to create an XML tree with fully qualified names. We can now take a look at how to associate a prefix with a namespace while creating an XML document.

Associating prefixes is just a matter of creating an XAttribute with appropriate values in the constructor and supplying it to XElemennt prefix is going to be associated with.



XNamespace ns = "http://www.essential.net"

var xml2 = new XElement("books",
new XElement(ns + "book", new XAttribute(XNamespace.Xmlns + "pre", ns),
new XElement("title", "Essential .NET"),
new XElement("author", "Don Box"),
new XElement("publisher", "Addison-Wesley")
)
);

XML Literals

As I mentioned in the beginning of this post that there is something in this API exclusively for VB.NET 9.0(+) developers. It is a new offering called “XML Literal” that enables developers to embed XML directly within VB.NET code. We have seen how to create book XML using Functional Construction above. Let’s now see how the same can be done using XML Literal:



Dim bookXML As XElement = <books>
<book>
<title>Essential .NET</title>
<author>Don Box</author>
<author>Chris Sells</author>
<publisher>Addison-Wesley</publisher>
</book>
</books>

bookXML.Save("book.xml", SaveOptions.None)

Rather than creating LINQ to XML object hierarchies that represent XML, VB guys instead can define the entire XML using XML syntax. And, If they want to make it more dynamic, they can also use ASP.NET code nuggets (<%= %>) which is called “expression holes” to embed the dynamic values into XML Literals.



Private Sub GetBookXML(ByVal bookName As String, ByVal publisher As String, ByVal ParamArray authors As String())

Dim customAttrib = "ISBN"
Dim bookXML As XElement = <books>
<book <%= customAttrib %>=<%= "0201734117" %>>
<title><%= bookName %></title>
<author><%= authors(0) %></author>
<author><%= authors(1) %></author>
<publisher><%= publisher %></publisher>
</book>
</books>

bookXML.Save("book.xml", SaveOptions.None)

End Sub

XML Axis Properties

Another unique feature which is available only in VB.NET 9.0 is “XML Axis properties”, which allows XML axis methods to be called using more compact syntax. Let’s take a look at those properties


  1. Child Axis Property
    This property allows all the child elements to return with a particular name. For example, I am looking for <author> element in my book XML. Using Child Axis Property I can directly say:
    Dim authorName as String = bookXML.<book>.<author>(0).Value 

    And, If you are interested in all the authors:
    Dim authors As IEnumerable(Of XElement) = bookXML.<book>.<author>
    Dim authors As List(Of String) = (From author As XElement In authors _
    Select author.Value).ToList()

  2. Descendent Axis Property
    It returns all the decedent elements that have the qualified name that is specified within the angle brackets. To see how it works, we’ll use the XML we produced using GetBookXML() method in XML Literal section explained above as input.


    Dim elements As IEnumerable(Of XElement) = bookXML. . .<title>.Where(Function(t) CInt(t.@ISDN) > 1)
    For Each e As XElement In elements
    Console.WriteLine(e.Value)
    Next

  3. Attribute Axis Property
    This property returns the string value of the attribute that has the qualified name that is specified after the “@” character.
    We have already seen an example of this property in the previous “Descendent property” section where we tried to get all the book titles by providing their ISDN property values to the WHERE clause.
    Another example could be a tiny piece of code that returns all the ISDN number in the entire bookXML document that we saved earlier.

    Dim ISDNList As New List(Of String)
    Dim elements As IEnumerable(Of XElement) = bookXML. . .<title>

    For Each e As XElement In elements
    ISDNList.Add(e.@ISDN.Value)
    Next

XML axis properties help a great deal in searching in XML documents. By having this shorthand syntax for accessing the primary XML axes, Visual Basic developers can stay focused on the XML they are trying to consume. As I said earlier, for the developers who deal with XML everyday, learning and understanding XPath is not a problem. However, for those like me who use XML rarely, Axis properties being a no-brainer has more attraction.


HTH,

Google dictionary tooltip – a cool thing

Have you ever seen something on the internet that surprised you a great deal? I saw something cool today that made me realize that there are companies out there like Google© that do clever things in their work even if it is a very small thing. I am talking about Google dictionary extension for chrome which employs some cool techniques to render the tooltip arrow. I have seen a couple of tooltip implementations online like on LinkedIn® and Twitter, but all they do is use an image for the arrow and sometimes complete tooltip balloon as an image. What caught my attention in Google Dictionary balloon was the use of simple plain html divs, and after I dug deeper, I realized there is no magic going on in there. Check this out.

Using chrome on a Wikipedia page for “Programmer”, I look up the meaning of this terminology in Google dictionary.

img-01

 

I do an “Inspect element” to see what styles arrows has.

img-02

 

The div I am interested in is next to the div with class “gd-bubble”, which is just a container for two inner divs which are creating the arrow effect. If you click the second inner div of this container, you can get all the styles. In order to figure out what exactly is happening there, I give some different colors to its borders (left,right and top).

img-04

 

As soon as I give the colors, it (second inner div) will look like this:

img-03

 

Next, in addition to border colors, I now try to change its height and width and see what happens.

img-05

 

It is now time to touch the first inner div as well. We give a green color to its top border (border-top) in order to distinguish it from its sibling (second inner div). The result I get is this:

img-06

 

To my surprise, the tooltip arrow is nothing but just a box with its bottom border (border-bottom) stripped off. Now, In order to give it an arrow shape, what I have to do is reduce its width to zero.

img-07

 

And, changed the height to “auto”.

img-08

Now change the border colors of the second inner div back to “transparent”.

img-09

 

As well as change the border-top color of the first inner div back to “transparent” and there I go. What I get is not a multi-color box, but a nice tooltip arrow pointing downwards.

Untitled-10

 

I know tooltip is not a big thing, but the point is that at times even the smallest thing can make a big difference in the performance of the site. It doesn’t imply at all that using an image will slow down the rendering of the page for the image can be cached, but when I can use native html to accomplish something, then why not.

 

HTH,