|
Spaces home Mike Amundsen's INETA Ta...ProfileFriendsBlogMore ![]() | ![]() |
|
Mike Amundsen's INETA Talks and TravelsDetails on Mike Amundsen's INETA Talks and Travels
July 22 Emulating Enumerators in JavascriptDownload this code from my Yahoo! Groups web site. I've been doing a lot of work with JavaScript recently. My current work project has me thinking a lot about 'advanced' JavaScript, 'Object-Oriented' JavaScript, and things of that nature. And I've learned quite a bit! While sharing some of this with my friend Bob of Intensity Software, he encouraged me to blog more about what I'm finding. So I'm starting a set of short pieces on JavaScript that I hope prove interesting. Enumerators Are HandyNow that I'm writing more code in JavaScript, I'm finding that I use enumerators to make my code more readable and portable. While MSIE has an Enumerator built-in object, the Mozilla-based browsers do not. So I needed to come up with something that works across browsers. My solution takes advantage of a very powerful feature of JavaScript - associative arrays. Associative ArraysAssociative arrays are collections that link "keys" to "values." Nothing big there. But the way JavaScript deals with associative arrays is very powerful. You can access members of associative arrays either using the familiar key-index pattern ( Defining an Enumerator ObjectSo, using associative arrays, it's easy to create an enumerator pattern in JavaScript. Below is a simple code example:
// define enumerator
var Role =
{
Visitor : 0,
User : 10,
Author : 20,
Editor : 30,
Publisher : 40,
Admin : 100
}
That's all there is, really. Now I can write familiar JavaScript to access the members as needed. For example, I can use Iterating an EnumeratorSometimes I wants to step through a list of enumerator members. I might want to create a dropdown list to allow users to select a member. I might want to use this enumerator pattern to express a list of menu options and then iterate through those options to create a menu of links. There are lots of possibilities. Below is some code to 'walk' through an enumerator and create an unordered list to display on a web page.
var elm = document.getElementById("output");
var str = "";
var cnt = 0;
str = "<ul>";
for(r in Role)
str += "<li>" + r + ": " + Role[r] + "</li>";
str += "</ul>";
elm.innerHTML = str;
SummarySo that's it. I used JavaScript's associative arrays pattern to emulate enumerators that can work across all browsers that support JavaScript. I can use typical enumerator access patterns as well as iteration patterns to access the contents as needed. There are lots of other possible ways to use associative arrays within JavaScript. I'll leave that to you to explore until my next JavaScript post[grin]. Technorati TagsI tag my posts for easy indexing at Technorati.com June 24 XML Namespaces and SQL2005on my last INETA trip (to Plano, TX) i was asked a question about generating XML from SQL2005 that included support for XML namespaces. Unfortunately, I didn't have my act together at that moment and was not able to show off this cool feature of SQL2005. But it is actually very easy to generate namespace-enabled XML using a new feature of SQL2005 - the NAMESPACES keyword The NAMESPACES KeywordThere are a number of powerful new keywords in SQL2005 that make it easier to support XML. One of them is NAMESPACES. AS you would expect, this keyword is used to output XML from SQL Server that includes the proper namespace designations. For example, let's assume you want to create the following output from the AUTHORS data table from the PUBS database:
<rdf:RDF xmlns:xmlp="http://www.amundsen.com/rdf/xmlp/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description>
<xmlp:id>123-45-6789</xmlp:id>
<xmlp:firstname>mike</xmlp:firstname>
<xmlp:lastname>amundsen</xmlp:lastname>
<xmlp:phone>123-456-7890</xmlp:phone>
<xmlp:address>123 main st</xmlp:address>
<xmlp:city>byteville</xmlp:city>
<xmlp:state>md</xmlp:state>
<xmlp:zip>94609</xmlp:zip>
</rdf:Description>
</rdf:RDF>
Creating the query that results in the above output is actually pretty straight forward. I'll go through the steps below and toss in a few other nice features of SQL2005 along the way. Step-By-Step XML Namespace Output from SQL2005All you need to do is to build your query as you normally would. First, the simple SELECT statement to get the data you need: select * from pubs.dbo.authors Next you need to tell SQL Server to return an XML version of the data: select * from pubs.dbo.authors for xml raw, elements The above query is nice, but is lacking a very important item - the root element. This was a classic problem with SQL2000 - so much so that when Microsoft released the SqlXml assembly for .NET, they included a workaround method that allowed programmers to set the root on the client site. However, the release of SQL2005 gave the SQL team a chance to fix this omission. Now, all you need to do is add the ROOT keyword to your query like this:
select * from pubs.dbo.authors
for xml raw, elements, root('RDF')
One more thing. With the above format, each collection of fields is enclosed in an element called "row." Not too creative, and not what we need. You can control the enclosing element name for each row by decorating the ROW keyword with a string name like this:
select * from pubs.dbo.authors
for xml raw('Description'), elements, root('RDF')
So far, so good. We have solid (valid) XML output, but no namespaces yet. here's the secret sauce built into SQL2005. you preface the query with a list of namespaces to include at part of the root element. It works like this:
with xmlnamespaces
(
'http://www.w3.org/1999/02/22-rdf-syntax-ns#' as rdf,
'http://www.amundsen.com/rdf/xmlp/1.0/' as xmlp
)
select * from pubs.dbo.authors
for xml raw('Description'), elements, root('RDF')
Now the output includes xmlns elements in the root tag. That's good - we have namespaces now! However, we also need to decorate the various elements in the output with the proper namespace prefixes. That works like this:
with xmlnamespaces
(
'http://www.w3.org/1999/02/22-rdf-syntax-ns#' as rdf,
'http://www.amundsen.com/rdf/xmlp/1.0/' as xmlp
)
select
au_id as 'xmlp:id',
au_fname as 'xmlp:firstname',
au_lname as 'xmlp:lastname',
phone as 'xmlp:phone',
address as 'xmlp:address',
city as 'xmlp:city',
state as 'xmlp:state',
zip as 'xmlp:zip'
from pubs.dbo.authors
for xml raw('rdf:Description'), elements, root('rdf:RDF')
Note that I also cleaned up the element names and added namespace designations to the row and root elements. Now the final output will include XML namespace designations for each element as needed. Technorati TagsI tag my posts for easy indexing at Technorati.com April 24 Basic WS-Auth Example Using ASP.NET 2.0During one of my recent INETA talks, several people asked for examples of Web Service authentication. Unfortunately, my talk did not include any. It's been a while, but I finally found some time to put together a simple example built using ASP.NET 2.0 and Visual Studio 2005. NOTE: I've posted the ASP.NET 2.0/VS2005 project for this article in the Files section of the MikeAmundsen Yahoo! Group. The SOAP HeaderFirst, the way SOAP authentication works is by adding a special header to the SOAP message. This is a fundamental part of the SOAP message model; the ability to add an arbitrary number of custom headers to the message payload without changing the actually body of the message itself. In effect, we are adding 'out-of-band' content to the SOAP message. As long as both the sender and receiver understand the header items, everything works fine. For this example, I've created a simple SOAP header with two elements: username and password. Using VS2005 and ASP.NET 2.0, I can create class that holds this data. This will be the authentication header for my secure SOAP messages. Below is the entire class definition for the custom authentication header:
Note that my custom class "AuthSoapHeader" inherits from the SoapHeader class in the System.Web.Services.Protocols. that's all I need for now. The magic of authentication comes later. The Secure HelloWorld methodNow, I'm ready to create a secure Web Service method. Using VS2005, I add a new Web Service class to my Web project. Since it already contains a sample HelloWorld method, I'll just modify that method to require a successful authentication before returning requested data. Here's my service *before* adding the authentication header support:
And here's my service *after* adding the authentication header support.
Note that all I needed to do is add a public instance of the header class, then add an attribute reference that tells the ASP.NET runtime to expect a header. Finally, I add some code to check the contents of the header and act accordingly. If the header is missing, I throw a SOAP exception back to the caller. That's all there is to it. I now have a service that requires authentication. Next I need to create an ASP.NET WebForm that calls this service using the header. Calling the Secure Service from a WebFormCreating an ASP.NET WebForm that calls the secure Web service is not much different from creating a WebForm that calls a standard, unsecured, Web service. After using VS2005 to add a Web Reference, I'm ready to get an instance of the remote SOAP header and Web service class. I created a simple form with Username and Password input controls, a button, and a label to hold the results of the WS call. Below is the code that runs behind the button click event:
Notice that way to call a secured Web service is to first get an instance of any required headers, fill them out as needed and then attach these headers to the usual SOAP object before making the service call. As long as the headers are populated correctly, the call will complete as usual. There's nothing more to it. Now you know how to add custom authentication headers to any Web Service.
Technorati TagsI tag my posts for easy indexing at Technorati.com April 06 Speaking in Chattanooga April 11, 2006I'm looking forward to my trip to Chattanooga, TN on April 11th to deliver another INETA-sponsored talk. The Chattanooga Area .NET User Group (CHADNUG) has selected my Message-Oriented Architecture (MOA) topic for the event. This is currently the most-requested talk in my list and I really enjoy delivering it. I have been giving some variation on this talk for close to two years. I update it often and this year is no exception. This time, I'll be adding a section on supporting Ajax-enabled web clients. If you are close Chattanooga, check out thier web site and come on out to the event. I look forward to seeing everyone there! Technorati TagsI tag my posts for easy indexing at Technorati.com Wanted: URI DesignerSome regular readers know that, as part of my ongoing personal project to improve my ‘web-tech’ knowledge, I have been re-reading Tim Berners-Lee’s "Style Guide for online hypertext" and other related materials. One of the common messages from documents on this topic is the importance of well-composed and maintained web addresses or URIs. This got me thinking about (and paying more attention to) the common web addresses that I see in my browser. I must say, I don’t care much for what I see. What’s bad about common URIs today?Too often the URI I see in my browser address line is gibberish. Just try visiting any of the top news sites (news.yahoo.com, www.msn.com, news.google.com, etc.) and click on any of the links on the page. Usually the URI contains additional state information (?x=13&y=29&_docid=DUsor93FH). Almost always, the URI contains company or technology-specific information (page.aspx, document.jsp, article.cfm, product.php). And almost never could I share the web address with a friend by merely speaking it. This is all bad. So what is the definition of a good URI?The W3C has an excellent document called "Common HTTP Implementation Problems". In it there is a section devoted to "Understanding URIs." This section reads like a ‘best practices’ list for creating solid URIs. I urge everyone to take a few minutes to read though it and to bookmark it for future reference. I’ll lift two quotes from that document to clarify the need for good URI design when deploying web applications. Here’s the first quote: "A URI is a reference to a resource, with fixed and independent semantics." This sentence has quite a bit packed into it. For example:
So, a URI is a pointer so something. That pointer never goes bad, and that pointer stands alone (or, put another way, is easily shared). Here’s the second quote: "A common mistake … is to think [that a URI] is equivalent to a filename within a computer system. This is wrong. URIs have, conceptually, nothing to do with a file system." This might come as a shock to some web programmers. It is so easy to expose physical folders and files via a web server that, by default, most web sites simply reflect the file structure behind a web domain root. This, too, is bad stuff. Move a file, and the URI breaks. Ok, so URIs are non-changing, stand-alone pointers and *not* reflections of folder and file structures on disk. Maybe we do need a URI design! URIs are web queriesOnce you get over the idea that URIs are not physical files in folders, you are free to start thinking about what URIs really represent. In my mind, a URI is a ‘web query.’ By typing a URI, users are ‘looking for something’ out on the Internet. By now, most web users understand that there are up to three parts to a URI query:
I suspect that most users do not think very much about the above details, but most intuit them as they surf. I am often especially surprised by the sophistication of young web surfers. I have observed children who are quite happy to ‘hack’ away at a URI in order to find a document. They truly use the browser address line as a search tool! Anyway, if you accept the idea that a URI is (in some fashion) a web query, then you are free to actively *design* the URIs for your web application to support this kind of use. To paraphrase the words of Tim Berners-Lee, you can make your URIs ‘hack-able.’ Creating hackable URIsWhat’s a hackable URI? In its simplest form, it’s a URI that can be easily modified by a user in order to get a valid result from the same server. The most common way to think about hackable URIs is to make sure that all sub-parts of the URI return a valid document. As an example, the URI "www.myserver.com/content/programming/tutorials/hackable_uris.html" has several sub-parts. Users who 'land' at this location should be able to 'lop off' parts of the URI and get helpful results. That means that the URI "www.myserver.com/content/programming/tutorials/" should return something – maybe a page that lists all tutorials. And "www.myserver.com/content/programming/" might return a list of programming article classes such as "tutorials," "reference," "bookreviews," etc. And so on.
But creating hackable URIs doesn’t mean just supporting sub-parts. It could also
mean using a user-friendly URI scheme that actually *invites* URI hacking. For
example, what can you assume if you land at a URI that looked like this?
Not only can you assume that you can get valid documents at each sub part. You can also assume that you can change the value of some sub-parts to discover new documents, right? So how do you implement a URI design?Once you start thinking about a URI design pattern that works for your site, you need to come up with a way to implement it. In the past, web programmers would start creating folders and files to match the stated design. This is not the way to go about it. Instead, web programmers should design a server-side scripts that can scan the incoming URI, treat it as a request query and assemble a response accordingly.
For example, given the following query:
A server might return a list of poets. Users might also assume that they can get
lists of other authors by changing the URI like this:
The point is that web servers should be able to do more than just serve up documents from a physical folder tree. One way to do this (using ASP.NET, for example) is to use the Uri.Segments collection to inspect and parse the URI. Here’s a trivial example. Given the URI www.server.com/archives/2005/12/ a server could create a query against a database table called "archives" for a list of documents added to the system in December of 2005.
Here’s some code to parse the URI:
And here’s the output created by the above code:
Submitting the above query might return a data set that could be formatted into an HTML page containing a series of links for the user to explore. OK, I get the idea, but there’s more to it, right?Well, yes. Knowing that URIs are static, independent resource pointers that should be ‘hackable’ by users and that ASP.NET has features that allow you to parse URIs into parts that can be used to create data queries is just the beginning. But you can use this information to create a more flexible and long- lived URI design for web apps. And with a URI design in place, you are no long dependent on the existence (or lack there-of) of physical documents within your web. There are also a number of other operations needed to support a good URI design. While good URIs don’t change, content does. Well-implemented URI responders will need to handle moved documents (HTTP 301 and 302 events) through a lookup table or some other means. Also, once you start to train users to ‘hack’ URIs at your server, you’ll need to add improved support for 4xx (not found) and possibly 5xx (server error) events to tell users when their creative URIs fail. In a future article, I’ll outline a URI design that I’ve been contemplating for some time. I also plan to share my implementation for this new URI design sometime soon. But don’t wait for me. Start designing and implementing your own backable URIs! Technorati TagsI tag my posts for easy indexing at Technorati.com
|
||||
|
|