ASP.nethttp://www.geekzilla.co.uk/Innovation Team's dumping grounden-usTue, 10 Jun 2003 04:00:00 GMTTue, 10 Jun 2003 09:41:01 GMTGeekZilla.co.ukeditor@GeekZilla.co.ukwebmaster@GeekZilla.co.uk Nested Master Page Events not being called http://www.geekzilla.co.uk/viewE07AA87A-F88E-4570-A504-4FB5FED36F56.htm Nested Master Page Events not being called This is the second time I've been caught out by this little feature, so I thought I'd geekzilla it for both reference and to help others. Scenario I'm a big fan of MasterPages and Themes as a design principle for web development, and often you need to nest master pages to create complex repeatable layouts. The Feature In my child MasterPage I decided to put some code in the Page_Load to populate a related menu, and it wasn't being called....... very strange.. The Top level MasterPages' events were being called, but the child's weren't! Solution I'm not sure why it defaults to false but.. you need to change the AutoEventWireup property to '''true''' in the Master Directive in the MasterPage. If this has caught you out, here's the solution. 9/10/2008 http://www.geekzilla.co.uk/viewE07AA87A-F88E-4570-A504-4FB5FED36F56.htm Displaying XML just like Internet Explorer http://www.geekzilla.co.uk/viewD245BBE0-2EAB-44C0-9119-8038467926EE.htm Displaying XML just like Internet Explorer This is everything you need to display XML in your webpage the same way IE displays it when you open an XML document in IE. Html Register the js and place a literal where you'd like the XML to appear. Code Behind Some dummy XML for this example The following applies an XSLt to your xml XSLt The XSLt required for the transformation CSS JS The JavaScript required to expand and collapse the XML document nodes. 4/1/2008 http://www.geekzilla.co.uk/viewD245BBE0-2EAB-44C0-9119-8038467926EE.htm Set Input Focus on a Control Programatically Added to an ASP.Net Page http://www.geekzilla.co.uk/viewF0289359-2C7F-483A-BFCE-B2B004B89996.htm Set Input Focus on a Control Programatically Added to an ASP.Net Page This little problem had the potential to drive me nuts for hours, I was fortunate to stumble over a blog with 100s of comments re problems of this nature and how to solve it. Most of the discussion was about using JavaScript, then I remembered I was using AJAX in my project and created a solution. '''The Problem''' I had a web page that automatically adds and removes TextBoxs based on a user's input e.g. a user may select "yes" in a DropDownList to a question and we need to get more information, so we add a Please Specify textbox on the postback of the DropDownList . But how on earth do you set the focus?? I tried adding the control to the page and then using its focus command, which didn't work. :-( '''Solution''' Luckly I was using Ajax on the page and I had a ScriptManager in the MasterPage. The script manager pumps out JavaScript, so I used a method on it to set the focus of the control using its client ID. This is the unique ID it is given on the page. Thank goodness for Google. I hope this helps you out.. 1/12/2007 http://www.geekzilla.co.uk/viewF0289359-2C7F-483A-BFCE-B2B004B89996.htm Dynamically adding a CSS link to the page in c# http://www.geekzilla.co.uk/view3214BB4D-8DAC-4149-9168-0D1F7D357432.htm Dynamically adding a CSS link to the page in c# The following code adds a CSS link to the header node of a Html page. 14/11/2007 http://www.geekzilla.co.uk/view3214BB4D-8DAC-4149-9168-0D1F7D357432.htm Preventing Caching of an ASP.net page in c# http://www.geekzilla.co.uk/view4198D1B2-65AE-4632-B45E-164EE86C790B.htm Preventing Caching of an ASP.net page in c# The following code prevents a page being cached. 5/11/2007 http://www.geekzilla.co.uk/view4198D1B2-65AE-4632-B45E-164EE86C790B.htm Getting the Virtual Path of a Request in c# http://www.geekzilla.co.uk/viewC93F8521-8014-4CB9-8989-F2E2403A8D76.htm Getting the Virtual Path of a Request in c# This simple bit of code will get you the '''Virtual Path''' of your current request. Example Usage Notes Don't forget to include: 5/11/2007 http://www.geekzilla.co.uk/viewC93F8521-8014-4CB9-8989-F2E2403A8D76.htm Fixing Form Action on UrlRewrite (UrlRewriter) http://www.geekzilla.co.uk/view0472D2E7-4653-46B1-AC36-5EA246B17D22.htm Fixing Form Action on UrlRewrite IF you're rewriting URL's, you've probably come across the same problem I had. When posting back on the page, the real URL is used.. this is a real pain if you're writing a page which uses the '''RawUrl''' to serve up relevant content. I had a good look around the web for a solution. These ranged from creating a custom HtmlForm control to replacing the form tag in the App_Browsers folder. The following is simple and worked for me. Place the following code in the Page_Load of the page you're serving up. Hope this helps. 5/11/2007 http://www.geekzilla.co.uk/view0472D2E7-4653-46B1-AC36-5EA246B17D22.htm Custom Validators using Client Side JavaScript http://www.geekzilla.co.uk/viewD27B15B4-71A4-4258-81EE-9445FAA9F634.htm Custom Validators using Client Side JavaScript In my latest project I am really enjoying using the Ajax Control Toolkit, particularly the ModalPopupExtender. I've been using the popup panels to capture data, but I needed to validate the data that a user enters into certain fields. ASP.net's validators are the obvious choice, but when you have employed an AJAX control you need to validate the entry on the client's browser. This is easy to do using the '''ClientValidationFunction''' attribute of the validator. then create a JavaScript function to do the validation. Here I have created a Regular Expression to validate decimals. Then simply set the args.IsValid property to either true or false and return. In this example I have used the ScriptManager to write out a JavaScript variable ('''DiscountPercentageId''') with the ClientID of the ASP.net TextBox I'm validating. You'll also notice my GetElement function to handle the browser compatibility. I hope this proves useful in your next AJAXian web application. ;-) 2/11/2007 http://www.geekzilla.co.uk/viewD27B15B4-71A4-4258-81EE-9445FAA9F634.htm Creating your first ASP.NET AJAX 1.0 Application http://www.geekzilla.co.uk/viewB6B709B4-5697-40EE-8429-CB09A453A94F.htm Creating your first ASP.NET AJAX 1.0 Application Over the last year or so, AJAX has taken the web development world by storm. AJAX is short for Asynchronous JavaScript and XML and is an approach to building dynamic web applications that behave less like the static web pages we're used to and more like desktop applications. At the heart of AJAX is the XmlHttpRequest object, a component originally designed by Microsoft and used to provide the rich Outlook-like interface of Exchange Web Access. JavaScript on a web page can use an instance of XmlHttpRequest to send requests to the web server that generated the page and then use the response to update part of the page, without the browser having to reload everything. This can make the application a lot quicker -- instead of the entire page having to be transmitted and rendered, the browser just fetches what's needed to update the current page. Although the technologies that support AJAX-style web apps have been around for years, they weren't widely used until the introduction of frameworks that made dealing with the extra complexity, not to mention cross-browser differences, possible. {Microsoft's ASP.NET AJAX framework}http://ajax.asp.net/ is one of the most recent, and has just been released as version 1.0, following a year of pre-releases that used the code name "Atlas". This article shows you how to AJAX-enable an existing ASP.NET web page by using Microsoft's ASP.NET AJAX Extensions. The UpdatePanel control provided by the framework makes it really easy to start with AJAX programming by defining the areas of the page you want to update independently without a full page reload. Once you've understood the basics, you'll use an {InnerWorkings}http://www.innerworkings.com/ coding challenge that provides a sample AJAX-enabled bug tracking website to help you really understand how to use the AJAX Extensions. [[bugtracker.png]] What is Microsoft ASP.NET AJAX? Microsoft ASP.NET AJAX is a free framework designed to make it easier to write modern AJAX-style applications using ASP.NET. There are two parts to the framework -- a cross-browser JavaScript library and a set of server-side ASP.NET controls. The JavaScript library goes beyond simply enabling AJAX apps and provides object-oriented extensions to JavaScript to make it easier to write complex applications that need to process a lot of data in the browser. On the server-side, a set of new and enhanced ASP.NET controls make it possible to write AJAX applications by simply adding controls to a page, just as with non-AJAX applications. In fact, you don't have to write a single line of JavaScript to create a fully-featured AJAX application. As well as ASP.NET AJAX itself, there are two other downloads available to add AJAX functionality to your site. The {AJAX Futures CTP}http://www.microsoft.com/downloads/details.aspx?FamilyId=A5189BCB-EF81-4C12-9733-E294D13A58E6&displaylang=en (Community Technical Preview) is a collection of new features which will be added to the main AJAX Extensions framework in the future. The {AJAX Control Toolkit}http://www.codeplex.com/AtlasControlToolkit contains prewritten components like panels that can be dragged around the page and rating controls to enable users to submit feedback. What's an InnerWorkings Developer Coding Challenge? An InnerWorkings Developer coding challenge is a sample of code in Visual Studio that has a couple of key pieces missing. Each challenge includes selected reference links chosen specifically so you can easily find out how to fill in the blanks, complete the sample app, and learn about a new technology at the same time. Once you're finished, InnerWorkings Developer automatically checks your code so you can be sure you've solved the challenge correctly and that you really understand what you've learned. The coding challenges are designed to take you to the heart of the technology you want to learn more about, focusing on the most important, practical features. Because everything has been set up for you, you can dive straight in and start coding. InnerWorkings Developer has a library of hundreds of challenges on topics from ASP.NET to Windows Communication Foundation. For more information, have a look at our {catalog}http://www.innerworkings.com/catalog . How Does the UpdatePanel Work? The UpdatePanel is designed to be the easiest possible way to AJAX-enable your site, focusing on the most important feature of AJAX: restricting updates to an area within a page instead of requiring a full refresh. Although it completely changes how requests are made by the browser, the UpdatePanel is written in such a way that your pages execute normally, which means you don't have to rewrite any controls or server-side logic. As the browser loads the AJAX framework, a JavaScript onsubmit handler is added to every form element on the page. When the form submits, the handler checks whether this should be a "partial update" -- one handled by an update panel. If so, it collects all the data being sent to the server, repackages it, and sends it, not as a regular browser request, but using the XmlHttpRequest object. In the browser, the onsubmit handler now returns false, effectively telling the browser to cancel the full page refresh. Meanwhile, the request has made its way to your web server looking just like a normal request with one difference: an extra HTTP header lets the AJAX infrastructure know that this is a partial update. The page executes as normal and the output is collected ready to be sent to the browser. Just before it's sent however, another bit of AJAX magic kicks in. Everything that isn't needed for the UpdatePanel is stripped out and some extra data is sent (including updated hidden fields and ViewState for controls not included in the UpdatePanel). When this arrives back at the browser, the JavaScript library updates everything, including the contents of the UpdatePanel, but also all the extra data. If your ASP.NET page updates the page title or even the page's CSS styles, all of these are updated automatically. Using the UpdatePanel Despite all this automatic support, using the UpdatePanel couldn't be simpler. There's a little install work -- once the AJAX extensions are installed, there are only a couple of additions to your web.config file to paste in. (The easiest way to add these is simply to copy the sample config file which should be installed to C:\Program Files\Microsoft ASP.NET\ASP.NET 2.0 AJAX Extensions\v1.0.61025\web.config or somewhere similar, depending on where you installed the extensions.) After that you can AJAX-enable your website by adding just two tags to your webpage: a ScriptManager and the UpdatePanel itself. The ScriptManager control manages the AJAX JavaScript libraries and writes <script> tags to tell the browser what to download. This process is mostly automatic, although you can also configure the control to include your own scripts, or to generate JavaScript for calling web services hosted on your server. To add a ScriptManager to your page, just add a ScriptManager tag to any server-side form within the page. The UpdatePanel is used to define the section of the page that should update without a full page refresh. To use the default features, just enclose the part of the page you want to AJAX-enable in a matching pair of UpdatePanel and ContentTemplate tags. In the example below, the SubmitButton and ResponseLabel tags are inside the UpdatePanel -- when the SubmitButton is clicked, a message appears without the page refreshing. To see how the page updates without using AJAX, you can comment out the UpdatePanel and ContentTemplate tags, leaving the Button and Label tags in place. [[birthday.png]] Try It Out As you can see, adding the UpdatePanel to an existing page couldn't be much simpler, but there's a lot more to the AJAX extensions than just the UpdatePanel. A great place to start if you want to see what's possible is the {ASP.NET AJAX showcase}http://www.asp.net/ajax/showcase/default.aspx . Next, download the {free ASP.NET AJAX Drill}http://www.innerworkings.com/promotions/c8226eee-ac57-4603-995b-0a766a3a20cb/geekzilla-ajax-promotion from InnerWorkings and see how to use the Update Panel in a real application. Once you've solved the challenges it contains, you'll know you're ready to start using AJAX in your next project. 7/9/2007 http://www.geekzilla.co.uk/viewB6B709B4-5697-40EE-8429-CB09A453A94F.htm Display CreateUserWizard Error Messages using a ContentTempate http://www.geekzilla.co.uk/view521AFCB5-0CB8-4FFD-A45A-2EE24ADC7FFE.htm CreateUserWizard Error Messages using a ContentTempate In our latest project we are implementing Membership, Roles and Profiles. I've used these before, but never really had the need to exploit all the features. The business requirements of the system have meant that I have had to implement a custom CreateUserWizard ContentTemplate, which is great feature of the control. I can set all of the error message properties, but I just couldn't work out how to get my custom error text onto the screen. I even tried putting code into the '''OnCreateUserError''' event to trap an error and display the error text, and this doesn't work because the error text in the event isn't what you specified in the control. After trawling the web, I found the solution. The Control must look for this literal when it is in error, and populates it. :-) How easy was that?! I'd normally close by suggesting a beer, but its too early on a sunday.. :-( Hope this helps someone. 12/8/2007 http://www.geekzilla.co.uk/view521AFCB5-0CB8-4FFD-A45A-2EE24ADC7FFE.htm Error connecting to undo manager of source file xxxx.aspx.designer.cs http://www.geekzilla.co.uk/view6B84F013-FEBA-4B81-8A3E-FCE1D720B867.htm Error connecting to undo manager of source file '''The Problem''' If you are using the Web Application Project Template (with as the Add On or as part of SP1) you can get this error. This error can simply appear at any time for no apparent reason. There have been several suggestions on the web on how to get around this involving excluding files and rebuilding. These solutions will not work if it is a referenced page or user control though. '''The Solution''' * Delete the offending designer file * Right click on the aspx or ascx and choose '''Convert to Web Application''' * Done 3/8/2007 http://www.geekzilla.co.uk/view6B84F013-FEBA-4B81-8A3E-FCE1D720B867.htm Returning a value from a PageMethod http://www.geekzilla.co.uk/view30F417D1-8E5B-4C03-99EB-379F167F26B6.htm Returning a value from a PageMethod using MS AJAX '''NOTE: This is designed for v1.0.61025.0 of AJAXExtensionsToolbox.dll''' If you've ever returned data from a web service using MS AJAX this technique will look familar. Call the method from javascript by append PageMethods. to the front of the method name. Add a delegate to the end of the method's parameters to get the result. I have made the source to this available to download, otherwise take a look at the full explanation below: Full explanation - Step 1 - Enable Page Methods on your ScriptManager Set the '''EnablePageMethods''' attribute to true Step 2 - Mark your method as static and give it the '''WebMethod''' attribute The method has to be declared '''static'''. It must also be marked with the WebMethod attribute. You'll probably find that you need to include System.Web.Services Step 3 - Call it from Javascript Call the method from javascript by append PageMethods. to the front of the method name. Add a delegate to the end of the method's parameters to get the result. 26/7/2007 http://www.geekzilla.co.uk/view30F417D1-8E5B-4C03-99EB-379F167F26B6.htm Getting the ProviderUserKey for the Current User http://www.geekzilla.co.uk/view26C30C80-3868-45A5-A4B8-983630AAE20B.htm Getting the ProviderUserKey for the Current User The following gets the ProviderUserKey for the current user. #c#(Guid)Membership.GetUser().ProviderUserKey 24/7/2007 http://www.geekzilla.co.uk/view26C30C80-3868-45A5-A4B8-983630AAE20B.htm Rendering a Control to a String http://www.geekzilla.co.uk/view82C6D636-C440-43CF-A443-E9BBFEA2BD5D.htm Rendering a Control to a String This is a really handy little function for rendering a control to a string. Really handy if you want to pass back rendered HTML from a StaticPageMethod or WebService. 12/7/2007 http://www.geekzilla.co.uk/view82C6D636-C440-43CF-A443-E9BBFEA2BD5D.htm ASP.NET Framework 1.1 Validation not working in IE7? http://www.geekzilla.co.uk/viewFF2FB9D4-28F7-4289-BEB3-6EA081A003EB.htm ASP.NET Framework 1.1 Validation not working in IE7? I recently had a problem with an old '''Framework 1.1''' website where the form would not post back if the page contained validators (CustomValidators to be exact). It caused me to do a lot of googling and in the end some javascript debugging. It was a strange problem, the site worked fine in IE6 and Firefox; just IE7 failed. Searching the web I was suppried that nobody else was complaining about this.. surely it was a 1.1 IE7 bug?? First clue In the onSubmit attribute of the form tag there is a call to '''ValidatorOnSubmit()'''. When Alerting this in JavaScript it returned '''"Undefined"''' I checked that the scriptmaps were ok and even reinstalled them using '''ASPNET_REGIIS -s <path>'''. Still no dice. The solution It turned out that .net '''Framework 1.1 SP1''' had been installed on the server but this site had local copies of the pre SP1 '''WebUIValidation.js''' file. I replaced the files with the correct ones and things started to work... sort of.. Problems with '''pre SP1''' code and the CustomValidator control The validation now triggered. Slight problem, it always failed, without even doing the postback it needed to perform server-side validation. The solution was to add a dummy custom validator function to allow client validation to pass client-side checks before doing server-side validation. #h#<ASP:CUSTOMVALIDATOR ClientValidationFunction="customvalidatorDummy" ... /> 4/7/2007 http://www.geekzilla.co.uk/viewFF2FB9D4-28F7-4289-BEB3-6EA081A003EB.htm LoginStatus not logging users out? http://www.geekzilla.co.uk/viewEDD6EAD5-E7AD-401F-A471-79EFF5C01A04.htm LoginStatus not logging users out? Have you noticed your '''LoginStatus''' control doesn't log the user out when you click '''Logout'''? Well, to fix this all you need to do is add an '''id''' attribute. This works This doesn't work Searching the web, there are a lot of people complaining that the LoginStatus doesn't work properly. Solutions are rare, special thanks to Ric Hayman for finding this. 18/6/2007 http://www.geekzilla.co.uk/viewEDD6EAD5-E7AD-401F-A471-79EFF5C01A04.htm XMLHTTPRequest in Stored Procedure http://www.geekzilla.co.uk/view24CF9B2B-4099-4ED7-B360-89B14C11DAE8.htm XMLHTTPRequest in Stored Procedure I recently had a requirement to call a webservice from a stored procedure. I looked into doing this by writing a CLR assembly in SQL 2005. There were a few articles online describing this but working in a large organisation I knew that getting the thing working on my development was only 20% of the battle. The XML serialisation of the web service request/response cannot be done natively, a separate assembly needs to written to achieve this, using a tool such as SGEN.exe. Basic objects such as HTTPRequest are not available in the SQL CLR so you can't just avoid the serialisation. Even once I had all that working, the idea of our database team deploying assemblies to their databases just seemed like a dream. So I looked for a simpler method and found that I could create an XMLHTTPRequest within a stored procedure much like I would in client-side code for an ajax solution. The stored procedure is below... You also need to enable Ole Automation for this database using... So basically your T_SQL can now make http requests, but not web service requests. The page I am requesting will be written in C# and will make the web service request itself, in an environment that is not so restricted as the SQL CLR. The added benefit is that this does not require 2005 to work, it should work on any SQL Server database v7 onwards Please beware: Your application login will need access to run the sp_OAxxx extended procedures, so you will need to ensure that this isn't something that just anyone can login as. I have read that teh user needs to in the sysadmin role - I have found that just GRANTing EXECUTE permissions for your user on each xp is enough. Also, do not make http calls from within a trigger, this can potentially cause really bad performance, especially where the web server is not reachable or responding for whatever reason. 16/5/2007 http://www.geekzilla.co.uk/view24CF9B2B-4099-4ED7-B360-89B14C11DAE8.htm Using a .Net 2.0 anonymous delegate when generating a thumbnail http://www.geekzilla.co.uk/viewD6A23BCB-04BD-4321-9CE8-630A54F30EF3.htm Using a .Net 2.0 anonymous delegate when generating a thumbnail Rather than using a mehod which does nothing except return false. Use a .Net 2.0 anonymous delegate for the GetThumbnailImageAbort parameter. Example 14/5/2007 http://www.geekzilla.co.uk/viewD6A23BCB-04BD-4321-9CE8-630A54F30EF3.htm Json converters lacking in Microsoft AJAX RTM http://www.geekzilla.co.uk/viewFB6CC06E-A638-428B-8A60-8C64887BA750.htm Json converters lacking in Microsoft AJAX RTM Having spent some time developing a project using a CTP version of Microsoft Ajax ("ATLAS" back in the day) I finally came to migrate the project to the RTM version. After uninstalling the CTP release, and installing the RTM release I wasn't surprised to see the project no longer compile. But once the basic problems were fixed (mainly name changes, tag prefixes, and a new [scriptservice] attribute for your web service classes) I was still seeing errors in the application. One of the main problems were errors of 'System.InvalidOperationException: A circular reference was detected ...' when calling a webservice that returned a DataTable or DataRow[]. The UI of this project was pretty much built on client-side calls to update and select data in this way, so suddenly I had a lot of select methods that stoped working (and in a project with 300+ stored procedures behind the scenes this was a headache!) I expected a few niggles but what I didn't expect was that the Json converters for DataTable and DataRow were no longer included (DataSet too I guess, but I wasn't using that in this project). I noticed that the references to the converters in the web.config were commented out and replaced with: ... 'that doesn't look right', I thought. Having seen online that the January 2007 CTP release had solid Json converters included I decided to use these rather than write my own (although that does look interesting :-) ). It turned out to be not too hard to get this working. All that is required is to replace the converter/add elements with those from the January CTP And to add the January CTP Microsoft.Web.Preview.dll file to the bin directory of your project (or the Global Assembly Cache if you prefer). To get file with the converters I had to download the Jan CTP, install on a virtual machine (I didn't want to run the CTP install after the RTM one) and copy the one file I wanted. To save you the hassle I have attached the file below. I was using a pretty old beta and in some cases had to refer to column values via a getProperty method... ...these had to change to directly accessing the column value as a property... ...which I prefer, even though it involved rather a lot of typing in this instance. Hey presto, my javascript was able to see my data again. That was all I had to do to migrate this section of my project. If you have the same problem with passing Data tables out of web services back to javascipt, then follow the tips above and all will be well :-) 6/5/2007 http://www.geekzilla.co.uk/viewFB6CC06E-A638-428B-8A60-8C64887BA750.htm Handy fake latin generator http://www.geekzilla.co.uk/viewB20C8CB9-EB60-4C33-9BC2-A9506E5EF4D8.htm Handy fake latin generator 4guysfromrolla have a handy "fake latin" generator. It allows you to specify the number of paragraphs to generate. Source available too, although old asp. http://www.4guysfromrolla.com/demos/latin.asp?paras=2 18/4/2007 http://www.geekzilla.co.uk/viewB20C8CB9-EB60-4C33-9BC2-A9506E5EF4D8.htm CAPTCHA Server Control http://www.geekzilla.co.uk/viewD5ACA281-0AAC-4C06-A411-8BAE9FCDED8D.htm CAPTCHA Server Control I have been searching Google for a way to quickly implement CAPTCHA on one of my web sites and came across this article at The Code Project. http://www.codeproject.com/aspnet/CaptchaControl.asp http://www.codeproject.com/aspnet/CaptchaControl/captcha-control.png 4/1/2007 http://www.geekzilla.co.uk/viewD5ACA281-0AAC-4C06-A411-8BAE9FCDED8D.htm "This row already belongs to another table" Error http://www.geekzilla.co.uk/view37EB5230-5B79-4D00-800C-52D7A46CFB15.htm "This row already belongs to another table" Error What an annoying error!! I couldn't believe that I couldn't just add a Row from one DataTable to another, while looping around a DataTable's Rows. It turned out to be slightly more complicated than the code I had written, I've simplified the code below from what I was actually doing in the loop, but you'll get the idea. The correct way to achieve this is to clone dt2 on dt1, this creates the appropriate columns, then when you want to copy the row from dt1 into dt2 you use the ImportRow Method. Once I'd found the solution to this problem it made perfect sense. If you've just got this error, I hope this helped you out. :-) Time for a (b) 24/10/2006 http://www.geekzilla.co.uk/view37EB5230-5B79-4D00-800C-52D7A46CFB15.htm Google Applicance - googleoff / googleon Tags http://www.geekzilla.co.uk/viewC8614968-56ED-4729-9C12-F01677DAC412.htm Google Applicance - googleoff / googleon Tags '''I came across these recently... thought I'd share''' ;) The googleoff/googleon tags disable the indexing of a part of a web page. The result is that those pages do not appear in search results when users search for the tagged word or phrase. For example, some developers use googleoff/googleon tags to comment out a navigation bar in static HTML pages. You can use googleon/off to tell the Google Search Appliance to ignore portions of a page. Insert <!--googleoff: index--> at the point you want the Google Search Appliance to stop indexing, then insert <!--googleon: index--> where you want it to resume indexing the page. You can also use the tags to avoid indexing anchor links leading to another web page. You can use either of the following to prevent the words "chocolate pudding" from appearing in the snippets. The googleon/googleoff tags are index, anchor snippet, all. Here's how they are used. index tag Words surrounded by the googleon/off tags will not be indexed as occurring on the current page. A page containing: has the terms "fish" & "mackerel" indexed for that page, but will not index "shark" for the page. It's possible, however, that the page could be a search result for the search term "shark", since "shark" may occur elsewhere on the page, or in anchortext for links to the page. anchor tag "Anchortext" surrounded by the googleon/off tags and occurring in links to other pages will not be indexed as words associated with the other linked-to pages. A page containing: will not cause the word "shark" to be associated with the page "linked_to_page.html". Otherwise, this hyperlink could cause the page "linked_to_page.html" to be a search result for the search term "shark". snippet tag The text surrounded by googleon/off tags will not be used to create snippets for search results. all tag Turns on all of the attributes: index, anchor, and snippet. The text surrounded by googleon/off tags will not be indexed, followed to another linked-to page, or used for a snippet. _thanks to Google for this content_ 27/9/2006 http://www.geekzilla.co.uk/viewC8614968-56ED-4729-9C12-F01677DAC412.htm Typed Masterpage reference http://www.geekzilla.co.uk/view674ECBC1-7CC3-486E-A580-E4B048E1E3D5.htm Typed Masterpage reference ASP.NET master pages are pretty handy and here is a simple tip to make them even easier to use. Using the MasterType reference in your content page allows you to refer to your master page properties without having to cast it to your master page type everytime. For example... allows me to write... rather than... Which saves you a little typing and provides intellisense 22/9/2006 http://www.geekzilla.co.uk/view674ECBC1-7CC3-486E-A580-E4B048E1E3D5.htm Authenticated HTTPRequests (Using Credentials) http://www.geekzilla.co.uk/viewC5E6201A-DFC1-4091-8145-5A893504C0E4.htm Authenticated HTTPRequests (Using Credentials) Recently I had to make a SOAP call to a Cisco CallManager (an IP PBX). This required that the request used basic authentication. I couldn't add a web reference as the cisco interface doesn't support GET requests, so the Visual Studio discovery fails - even after authenticating. It turns out that making a call to a webService is not too hard anyway and adding the credentials is just a single extra line of code, as shown in the sample below... This example uses the Cisco AXL interface to request a list of phones that match the description. 4/9/2006 http://www.geekzilla.co.uk/viewC5E6201A-DFC1-4091-8145-5A893504C0E4.htm Lightweight Ajax http://www.geekzilla.co.uk/viewC77497B2-2CD6-4FBC-968C-93AFF2F397EB.htm Lightweight Ajax Ajax doesn't have to be complicated - at its most basic it just means partial updates your pages rather than reloading the whole page. The attached js library contains just two functions - GetContent and RunJS. GetContent() takes a URL and a element name: It simply populates the elements innerHTML with whatever the URL returns. Optionally you can also specify to append to the div content rather than repalce. Run() takes a URL only: It simply runs whatever the URL returns. The simple example below shows how these can be used to create rich interface such as a node tree. The source for this is attached as a zip file below, but I'll summarsie here; The Default.aspx page references the Ajax.js file and contains a function init() that adds a few nodes. The variable 'node' is just a unique reference for each div - note that the GetContent() calls reference myDiv, myDiv1 etc. The Node.aspx file is pretty simple also; It just contains another <DIV> element and link to populate it, again using the GetContent() function. Because of the simplicity of the functions, integrating with other tools such as Rico is not complex. This is not a replacement for a framework such as ATLAS, but it is a lot easier to pick up if you just want to Ajax enable key functions in your existing application. 27/8/2006 http://www.geekzilla.co.uk/viewC77497B2-2CD6-4FBC-968C-93AFF2F397EB.htm Web service calls from javascript using ATLAS (part 3) - Complex properties http://www.geekzilla.co.uk/view7DA902AA-513E-48D2-AD02-0F1A1946A999.htm Web service calls from javascript using ATLAS (part 3) - Complex properties Part two covered returning objects with multiple properties from a webservice and accessing those properties from javascript. This article demonstrates that even 'complex' properties are supported by the ATLAS framework. A complex property in this context is one like below: The getVcard method returns some HTML in the vCard microformat. Your javascript stays nice and simple as below... The reason this works is that the javascript object is given each property from the .NET object by the ATLAS framework. If there was a property that showed the current time then the javascript version of the property would always show the time at which it was created. I have found this to be a useful to keep my code/logic where I want it - not embedded in HTML! 25/8/2006 http://www.geekzilla.co.uk/view7DA902AA-513E-48D2-AD02-0F1A1946A999.htm Web service calls from javascript using ATLAS (part 2) - Complex return types http://www.geekzilla.co.uk/viewF266ADEB-8F62-4E92-8036-1D2436C2DE3A.htm Web service calls from javascript using ATLAS (part 2) - Complex return types Following on from part one which showed how to make web service calls from javscript, this article will now show the flexibility of the ATLAS framework by calling a web service that returns an object from javascript. Lets expand from the previous example with the web service below... You need to add reference to this web service to your ASP.NET page. This is achieved in exactly the same way as before... You can now make JavaScript calls to the web service as shown below... I was very impressed that the properties of the c# class are now available to me in javascript. I hope you are too. I have to say, credit goes to Paul Hayman who originally pointed this out to me. Credit also to the ATLAS team of course! #$#<a href=http://www.geekzilla.co.uk/View7DA902AA-513E-48D2-AD02-0F1A1946A999.htm >Link to part three of this article</a> 25/8/2006 http://www.geekzilla.co.uk/viewF266ADEB-8F62-4E92-8036-1D2436C2DE3A.htm Web service calls from javascript using ATLAS (part 1) http://www.geekzilla.co.uk/view91E6FCCB-DB0A-499C-A2CC-9854452D2086.htm Web service calls from javascript using ATLAS (part 1) ATLAS provides a fantastic mechanism for making web service calls from javascript code. Take the simple web service below... You need to add reference to this web service to your ASP.NET page. This is achieved using the ScriptManager tag as in the example below... Infact only the Services and ServiceReference elements are added to the basic scriptManager tag. Note taht there seems to be a limitation in the CTP that I am using where the web service needs to be in the same web site as your project. This is a serious limitation but it shouldn't be too hard to create a proxy for any web service runing elsewhere until this is fixed in the next CTP. You can now make JavaScript calls to the web service as shown below... I hope you find the example useful in your own applications. 25/8/2006 http://www.geekzilla.co.uk/view91E6FCCB-DB0A-499C-A2CC-9854452D2086.htm Not using Google Analytics? You should be! http://www.geekzilla.co.uk/view007D79CE-12F0-4DE2-AAFC-79725A1A89BE.htm Not using Google Analytics? You should be! Over the past few days I have received a number of comments regarding a recent article I published about re-directing a Page by Appending an HTTP Header, and linking this with '''Google's Analytics''' '''PPC tracking''' for '''Affiliate''' click-throughs. Read it here AppendHeader. To cut to the chase, I thought I'd put together an article regarding '''Analytics''' and just how easy it is to implement in your code. Still not convinced? Then take a look at the screen shot below of '''GeekZilla's Analytics'''. All this information for free!! When combined with Adwords you can really understand how effective your marketing campaigns are with a clear view of your ROI. The Geo Map Overlay is a particular favourite of mine. We even have readers in Beijing. Getting started Okay, so I've got you interested. You'll need to sign up to Analytics first. Occasionally you'll be placed on a waiting list, this isn't a problem and you'll get access soon. http://www.google.com/analytics/sign_up.html Got an account, set up your site This couldn't be easier. From the main page simply click '''Add Website profile''' in the Website profiles box. From here simply enter your domain name and Analytics will generate the JavaScript snippet required to implement the tracking in your site. This is where '''ASP.NET''' comes into its own. Hopefully you will be using a '''MasterPage(s)''' in your application and you merely have to cut and paste the Analytics Snippet into the header of the document. If you're not using '''ASP.Net''' then use an include of some description or stick it in the header of each page if you have time on your hands. ;-) What's next? Once you've got your tracking Snippet installed, the Analytics application can check your tracking is installed correctly and it will start to receive data (generally 24 hours behind). You can exclude certain traffic by using the filter manager so you're not tracking your own hits. Conversion Tracking If you're running PPC campaigns you'll have a '''Google's Adwords''' account. Simply set up the conversions you want to track in the Conversion Tracking tool and Cut and Paste the generated snippet into your key pages. You can track Purchase/Sale, Lead, Signup, Views of a key page, or anything else you're interested in. You can even make use of the '''google_conversion_value''' variable by dynamically setting it based off the value of the sale, or if you're generating a lead and know the commission paid simply hard code it. This will give you a view of your ROI from your marketing campaigns. I hope this has been useful, and that you choose to use Google Analytics if you haven't made that choice already. 23/8/2006 http://www.geekzilla.co.uk/view007D79CE-12F0-4DE2-AAFC-79725A1A89BE.htm Auto-complete using ATLAS http://www.geekzilla.co.uk/view7585D539-C094-4211-9FFC-32FABE4D09B5.htm Auto-complete using ATLAS Setting up an auto-complete input box in ATLAS is pretty simple, here is a quick guide to illustrate this... Assuming you already have the ATLAS framework referenced in your project then select an <asp:TextBox> to apply auto-complete to. See Mark's article for adding ATLAS to an existing web site: http://www.geekzilla.co.uk/View2C00AD81-BA3C-4E02-A265-C2C3925B4B23.htm Start by adding the following auto-complete extender, referencing the TextBox object you want to extend... Note the ServiceMethod and ServicePath attributes, these specify the webservice and method that will take what the user has typed so far and return an appropriate list to select from. The web method definition should be as follows: The user input so far is passed into prefixText and maximum number of records to return is passed into count (although this is a 'recommendation' only - the control will show whatever count you return). The string[] returned will be displayed in the familiar auto-complete dropdown panel allowing the user to select a valid response either with the mouse or cursor keys. By default the auto-complete does not kick in until the user types a third character in the TextBox - this default can be overridden using the MinimumPrefixLength attribute. Consider that the webmethod will be called for every keystroke after this minimum so do ensure that the webmethod will return in a timely manner or a few users typing will generate significant load on your server. If your method is by necessity slow, then consider increasing the minimum prefix. Similar to with making web service calls from javascript (see http://www.geekzilla.co.uk/View91E6FCCB-DB0A-499C-A2CC-9854452D2086.htm) there seems to be a limitation in that the web service must be part of the same project. 22/8/2006 http://www.geekzilla.co.uk/view7585D539-C094-4211-9FFC-32FABE4D09B5.htm Creating a Tag Cloud in C# http://www.geekzilla.co.uk/view960C74AE-D01B-428E-BCF3-E57B85D5A308.htm Creating a Tag Cloud in C# I wanted to add a TagCloud to GeekZilla. The first thing I did was look around the web for some examples (or free components). To my supprise none jumped out at me. So, I decided to write my own. At first I found myself wondering how I would render different size words randomly within a <div>. How would I be able to position them in relation to each other? float:right?? After looking at a few tag coulds {de.licio.us}http://del.icio.us/tag/ , {dotnetkicks}http://www.dotnetkicks.com/ etc I discovered that tag clouds are infact displayed in alphabetical order and the word size doesn't change much. My Needs The TagCloud would need to be able to be generated from a DataTable containing the columns 'tag' and 'count'. In my case the data would come from a Sql Server 2005 database. At the database level I'd be doing the aggregation and ordering. The TagCould code would only need to worry about weighting the tags. The Data First of all I created a view of all tags with their grouping: I then created a stored procedure which would return me the top 60 tags ordered alphabetically: The UI I decided to place the tag control within a UserControl incase I needed to include it in more than one page, in the end it was only used in the MasterPage. I created a method called GetCloud() which would contain the logic for the tag weighting. The method accepts a DataTable and a String based Cloud Template. The Cloud Template is tokenised, the replaced version is returned for each tag in the DataTable. Next I included some validation on the input table. Now time to get down to business. To figure out the weight of the tag I first needed to know the Min and Max tag occurances. For this I used DataTable.Compute(). You can see more information on the Compute() method in my article about EvaluatingExpressions. With the Min and Max known I could loop through the DataTable figuring out the tag weight. First of all I needed to calculate the weight as a percentage. For this I divided the number of occuances by the maximum occurances and multiplied it by 100. With the weight percentage I apply a bunch of cascading 'if' statements to figure out which weight classification the tag belongs to Lastly I replace the tokens in the cloud template and append the result to a StringBuilder. When all are evaluated, return the StringBuilder CSS Ok, this code generates a bunch of Anchor tags. I'd need to use CSS to make the thing look decent. The cloud template used the weight to assign an appropriate style to each tag. The styles used are *weight1 *weight2 *weight3 *weight4 *weight5 The following StyleSheet was created to bring these tags to life within a '''<div>''' called '''tagCloud''' Adding my cloud to the UserControl Html The Html is really simple, as you can see below: Code Behind The '''Page_Load()''' calls my DataAccessLayer to get the DataTable and passes the data to the local '''GetCloud()''' method. Note the use of ResolveClientUrl The Result You can see the result of my efforts right here on GeekZilla, if you're interested in using or enhancing this code, feel free to download the example application linked from the bottom of this article. I hope my code makes your life a bit easier, if nothing else I hope it inspires you to add a cloud to your site... doesn't just have to be for tags ;-) 22/8/2006 http://www.geekzilla.co.uk/view960C74AE-D01B-428E-BCF3-E57B85D5A308.htm Custom Templated SiteMap Navigator Control http://www.geekzilla.co.uk/viewCD56F872-0BA9-4938-8BD9-A853AEFC7FF3.htm Custom Templated SiteMap Navigator Control After discovering the power of the SiteMap, especially when linked to Authentication, it wasn't long before binding the TreeView to the map was not enough. I needed to have total control over what was displayed to the user for each item, so I wrote a Templated SiteMap navigator control. It works in a similar way to an asp:Repeater so should be fairly easy to comprehend. Here is a very simple example of an implementation: The above code will render a '''<ul>''' as a header then a number of '''<li>''' list items representing each link. It works with nesting, each nest level will render a new header. Properties The control I've written exposes a couple of properties which tell it how to navigate the site map. These are: ||Property||Description|| ||'''FromCurrentLocation'''||Indicates that the control will render from the current page down.|| ||'''MaxDepth'''||0 based, sets which level to render from|| Lots of Templates I have included a number of templates which represent different states of the sitemap. This example excersised them all: The names of the templates should be enough for you to figure out what they do. Feel Free to download the code for this control, along with a very basic sample site. Enjoy it and kick it! #$#<a href="http://www.dotnetkicks.com/kick/?url=http://www.geekzilla.co.uk/ViewCD56F872-0BA9-4938-8BD9-A853AEFC7FF3.htm"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.geekzilla.co.uk/ViewCD56F872-0BA9-4938-8BD9-A853AEFC7FF3.htm" border="0" alt="kick it on DotNetKicks.com" /></a> 20/8/2006 http://www.geekzilla.co.uk/viewCD56F872-0BA9-4938-8BD9-A853AEFC7FF3.htm Redirect a page using a Header http://www.geekzilla.co.uk/view5F6A2CD2-1C3C-442A-8912-AA8C1BF360EA.htm Redirect a page using a Header Any keen surfer will be familiar with '''Affiliate Marketing''', its a huge industry with '''Google's Adwords''' driving "Pay Per Click" campaigns. '''Google''' provide the '''Adwords''' application and '''Google Analytics''' to track the effectiveness of marketing campaigns from click through, to page view, lead generation and sale, with the tracking easily implemented by inserting a small snippet of JavaScript in the page. So where does the Redirect fit in? '''Affiliate''' sites merely send clicks through to merchants via an '''affiliate network''', that tracks the referral and the conversion. But to capture the information required for '''Google's Analytics''' you need to stick a page in between the viewed page and the referral to execute the '''Google Analytics''' snippet. This is relatively simple and can be achieved a number of ways, but the best method I have discovered is to use the code below. In the Page_Load you simply append a '''Header''' to Refresh the page, set the time in seconds before the Refresh occurs and supply the URL. You won't find this in the source of the page as it's passed in the HTTP response headers to the browser. Other implementations of this solution? If you have a web application that requires a user to login, you can use this in conjunction with '''Session.Timeout''' to logout a user after a period of in activity between pages in the application. I hope you find uses for this in your next '''ASP.Net''' application. ;-) 20/8/2006 http://www.geekzilla.co.uk/view5F6A2CD2-1C3C-442A-8912-AA8C1BF360EA.htm Sending mail using Localhost and .Net 2 http://www.geekzilla.co.uk/view26D8B20C-4627-432D-9664-63AC43EAFDF8.htm Sending mail using Localhost and .Net 2 I came across an old favourite today when trying to send email using the SMTP service on Local host. The error was SMTP 550 5.7.1 Unable to relay for xxxxxx What you need to do is change the security settings on the SMTP Service to allow your to relay from your local machine. This is simply done in IIS Admin as shown below http://static.flickr.com/40/216738937_d2957f7dc3_o.png 16/8/2006 http://www.geekzilla.co.uk/view26D8B20C-4627-432D-9664-63AC43EAFDF8.htm Comparing ATLAS and Dojo (part 1) http://www.geekzilla.co.uk/viewFB84A137-B68F-4368-A12A-BE6B353F6287.htm Comparing ATLAS and Dojo (part 1) This is a first article in a series comparing some of the functionality of ATLAS with another popular AJAX framework called Dojo. Both frameworks have some powerfull components and there is a high degree of overlap. This first article is a straight comparision of the Dojo TitlePane and the ATLAS CollapsiblePanel components. Both components provide client side presentation of a content area with a title/header switch which allows the user to hide/unhide the content. First thing to note is ease of use. Despite the intelisense help in VS2005 it is still much easier to add the Dojo component. Once you have some bolier plate .js includes/definitions and register the TitlePane the code to add the functionality is trivial: Compare this to the ATLAS code, which still has some boiler plate to add the ATLAS ScriptManager: With ATLAS you have to link the behaviour (extender) to a control, the asp:Button. You will notice also that it works by having a panel containing the collapsing area inside another panel. Code wise it looks much more complex, however, this is mainly due to the additional properties and control you have around the collapsing area. For staters ATLAS supports horizontal and vertical collapsing. Also you can set the hide/unhide switch to be almost any other asp control. Documentation is currently thin on the ground for the Dojo control but it appears to create the switch area as a link or as a static text placeholder. So if you just want a simple collapsing area Dojo fits the bill. If you need much more control or different behaviour use ATLAS. I built two pages, one based on Dojo and one on ATLAS. Both used the same elements where possible, .css for instance. Both had three collapsible panels. For a simplistic performance test I ran a proxy and monitored GET request/response times and found the following results: || Dojo || || First request || 1.539 sec || || Cached requests || 0.572 sec || || ATLAS || || First request || 1.042 sec || || Cached requests || 0.807 sec || I ran Dojo with debug=true so some additional scripts were downloaded but this seems fair based on the beta basis of both frameworks. The initial Dojo page and scripts come in at a hefty 229204 bytes. The ATLAS page weighs in at 90392. So the basic performance results favour Dojo after the initial page request. Trying to come to some conclusion of this comparison is difficult. At the moment both frameworks are beta so not production strength. I would have to say depending on your WEB 2.0 efforts you might chose either. If you are trying to introduce some AJAX into an existing application then Dojo TitlePane is easier. If you are starting from scratch then you have greater range of function with ATLAS CollapsiblePanel. Choose the one which best suits your needs. 8/8/2006 http://www.geekzilla.co.uk/viewFB84A137-B68F-4368-A12A-BE6B353F6287.htm Programmatically adding LINKs to HTML HEADER in Code Behind http://www.geekzilla.co.uk/view03C1F8AB-0454-4821-9E98-A5E84BDB6F31.htm Programmatically adding LINKs to HTML HEADER in Code Behind In this example I am adding a link to the html header pointing to an rss feed. You can use the method above to add other resources, such as style sheets. 1/8/2006 http://www.geekzilla.co.uk/view03C1F8AB-0454-4821-9E98-A5E84BDB6F31.htm Return new identity from Strongly Typed Dataset DataTable.Insert method http://www.geekzilla.co.uk/viewF2737CEE-4FCE-4215-B8CA-74D77EF64A5F.htm Return new identity from Strongly Typed Dataset DataTable.Insert method Datasets are pretty good at auto generating stored procedures and wrapping c# code around them for you. However with the insert method you often want to do something with the object that you have just inserted. Fortunately there is an easy way to get the Sproc and the c# method to return a reference to the object. Firstly edit your insert stored procedure adding a @return parameter and a line after the insert to set this to a suitable value. The exmaple below assumes that you are using bigint identity fields. Note that SCOPE_IDENTITY() is similar to @@IDENTITY except its scope is limited to the current command and so improves scalability. Now when you save the Dataset you see that the insert method takes two parameters, the second being a nullable long. My first thought was that Datasets should be the end of editing stored procedures but I am still impressed that the c# method declaration changes accordingly. You can call the updated method in the following way. the long? just means nullable long. After filling the table you can now use the FindByxxxID functions of the DataTable to return the DataRow object. 27/7/2006 http://www.geekzilla.co.uk/viewF2737CEE-4FCE-4215-B8CA-74D77EF64A5F.htm TraceListener creates huge log files http://www.geekzilla.co.uk/view2C5161FE-783B-4AB7-90EF-C249CB291746.htm TraceListener creates huge log files If you've used the .Net trace listeners, you'll know that they just keep appending to the file specified in the App.Config file, this can lead to some massive log files! Here's a simple TraceListener that logs to a new file for every day. You can configure this by amending the App.Config file: So on the day of this submission this would create a file in e:\logfiles called mylogfile_20060726.log. 26/7/2006 http://www.geekzilla.co.uk/view2C5161FE-783B-4AB7-90EF-C249CB291746.htm Integrating Dojo Fisheye and SiteMapDataSource http://www.geekzilla.co.uk/view7535BF49-D29A-45E1-A436-6115CEE2F123.htm Integrating Dojo Fisheye and SiteMapDataSource Everybody seems to be getting excited over this AJAX thing. Even Microsoft are (at last... ok they started it with OWA) getting on the bandwagon with the Atlas libraries. Of course just because Atlas exists doesn't mean you cannot use some other snazzy client side AJAX toolkits and one of the richest is the '''Dojo Toolkit'''. It includes a rich set of components including a range of 'widgets' for increasing user productivity. They also add a wow factor. My current favourite is the '''Fisheye list bar widget'''. This renders an icon bar Apple Mac style which cycles in size smoothly as the user moves the mouse pointer over it. Having been asked to redesign an old commision I decided I would like to make use of the new ASP.NET navigation components but thought it would be cool to tie the data components to this Fisheye control and render a really slick navigation bar. There already have been some use of Dojo with ASP.NET and even intergrating it with Atlas but Fisheye is quite a recent widget addition and documentation is ongoing so to save you sometime here's what you need to do. Add the Dojo bootstrap .js and other widget .js libraries to your project. I added navigation to a master page. First add some boiler plate script to include set a debugging switch, include the Dojo bootstrapper and register the needed widget libraries: I decided to hold the site structure and navigation elements in '''web.sitemap''' and access it through the a '''SiteMapDataSource''' component. Then process each node and create the Fisheye list of items. The code below looks a bit messy but I will pick out some key features of the Fisheye widget: This code creates a vertical icon bar which when mouse-overed enlarge to the max size and swing out slightly from the left with a caption positioned on the right of the icon on which the mouse is over. The '''dojo-FisheyeList''' is defined in the widget library. Hopefully most of the settings speak for themselves. You can switch the '''dojo:orientation''' between vertical and hortizontal. '''dojo-attachedge''' specifies where the icons snap back to once they loose focus. '''dojo-labeledge''' specifies where the label (kind of tooltip) appears when a particular icon has focus. These two properties support top, bottom, left and right. The '''dojo-FisheyeListItem''' creates the link icon. Again the properties should be self explanatory. The '''onclick''' event links to some other custom javascript to handle navigation as defined in the '''web.sitemap'''. There are numerous uses for Dojo. Non widget libraries include function such as IO, encryption, logging and xml manipulation to name a few. And it includes support for JSON under the rpc components. In short this is a very rich toolkit and something all developers should give at least a once over. So if you have a few minutes to spare check out the demos at http://dojotoolkit.org/ and ''''see it in action''''. 25/7/2006 http://www.geekzilla.co.uk/view7535BF49-D29A-45E1-A436-6115CEE2F123.htm Extending web.sitemap http://www.geekzilla.co.uk/view79E6FCD7-64A5-425D-B2A9-734E199CA906.htm Extending web.sitemap If you are using '''ASP.NET''' you are probably already familiar with the new sitemap components. The '''sitemapdatasource''' and '''web.sitemap''' elements make it very easy to build and maintain rich site structures. Using the '''Eval''' statement and recursing across the '''siteMapNodes''' is a very powerfull yet simple mechanism which allows for some low level control of site navigation control rendering. Using a '''repeater''' control with ''''<%# Eval("title") %>'''' allows you to render the details as you want it. Problem comes when you want to extend the web.sitemap with some custom information. Using '''Eval''' throws an error as it appears to be constrained by schema on the '''web.sitemap''' file. This schema only allows a finite set of attributes. So suppose you want to have a custom attribute called '''icon''' which gets pulled into your navigation generation code to build a nice navi bar. The '''web.sitemap''' would look like: There are two choices at this point: 1. Build your own navigation provider with derives from '''StaticSiteMapProvider''' and override the required node navigation controls. This is straight forward but in some cases may be more work than you would like. 2. Rather than use an '''Eval''' use: For adding a few custom attributes choice 2 this seems a good solution. If your web.sitemap requirements include some changes to the node structure then you should implement a custom provider. 24/7/2006 http://www.geekzilla.co.uk/view79E6FCD7-64A5-425D-B2A9-734E199CA906.htm Extending Strongly Typed Datasets http://www.geekzilla.co.uk/view6FFCCB67-2483-437D-A6B6-08B378B5B23C.htm Extending Strongly Typed Datasets Strongly Typed Datasets are a rather nice addition to VS2005 (they don't lend themselves well to acronyms however) You still need to create a database and tables and realationships but using STDs saves a writing huge amount of code. If this code were generated by hand or by a utility such as CodeSmith then the classes could just be edited to add function as required (though most of the benefits of code generation are lost once the generated code is edited). The STD source is of course auto-generated from the xsd file, a convienient way to view the C# source is to type the STD name and use the context menu to 'Go To Definition', or press F12. This will open a c# source file with a guid name. You can edit this file but it will be overwritten each time the xsd is compiled. You can add new methods and properties to the STD classes by using partial classes. First create a new cs (or vb if you swing that way) file with the filename same as your xsd - for example 'ObjectSTD.cs'. Edit the class definition adding the partial keyword as below. You can add a new method to the ObjectRow class within the ObjectSTD class with the following code... Note that private properties and methods are available and intellisense supports these. 23/7/2006 http://www.geekzilla.co.uk/view6FFCCB67-2483-437D-A6B6-08B378B5B23C.htm Serializing abstract classes to XML http://www.geekzilla.co.uk/viewA9CF69B4-0C40-4CEE-A590-496D9EB09C0E.htm Serializing abstract classes to XML Digg it: http://digg.com/programming/Serializing_abstract_classes_to_XML_in_c It is often useful to have abstract classes with several derived types to allow use of strongly typed lists and the such. For example you might have a DocumentFragment class which is abstract and two concrete classes called TextDocumentFragment and CommentDocumentFragment (this example from Willis). This allows the creation of a List<DocumentFragment> property which can contain objects only of those two types. If you attempt to create a WebService that returns this list you get an error but this is easy to get around with the code below.... The XmlInclude attributes tell the class that it might be serialized to those two derived classes. This generates an attribute in the DocumentFragment element specifying the actual type, as below. Any additonal properties specific to the derived class will also be included using this method. 18/7/2006 http://www.geekzilla.co.uk/viewA9CF69B4-0C40-4CEE-A590-496D9EB09C0E.htm Parser Error Message: Ambiguous match found. http://www.geekzilla.co.uk/view627399E1-8F4D-4A0F-B60F-3FFC7EAFCCC8.htm Parser Error Message: Ambiguous match found. VS 2005 Only. This can be an annoying error, but it is usually caused by one thing. If you add an object to your html source such as By default this will be instatiated in the partial class that is created by Visual Studio 2005. ""However"", there is nothing to stop you specifing the object in the codebehind as well such as And while you are running in Dev this will continue to work, but as soon as you do a release build you will get the Parser Error Message when trying access the page. A pain but when you know where to start looking it does make it easier to solve the problem. 13/7/2006 http://www.geekzilla.co.uk/view627399E1-8F4D-4A0F-B60F-3FFC7EAFCCC8.htm Strongly Typed DataSets and GridViews http://www.geekzilla.co.uk/viewF9581DAE-CCF8-49FF-844C-7498603E0005.htm Strongly Typed DataSets and GridViews If you are anything like me you don't enjoy writing 5 or 6 stored procedures for each business object in your solution. If you do, then click here to read more about T-SQL! http://www.geekzilla.co.uk/Browse.aspx?CategoryID=32 For the rest of you I will add some notes about my recent experience with DataSets. Within VS2005 (or the express versions) you can drag a database table onto a DataSet object (an .xsd file generate using the 'Add Item' menu). This generates a DataTable and DataTableAdapter with the four standard SQL statements (Select, Insert, Update, Delete). You can then easily link a GridView to this TableAdapter via an ObjectDataSource. You then run the page it all looks fine, you click the Edit button and make some changes and then click Update. '''ObjectDataSource 'ObjectDataSource3' could not find a non-generic method 'Update' that has parameters: TestString, original_TestId, Original_TestString.''' Then you become less impressed, you have also clicked the Delete button first and noticed that it just didn't work. At this point you might look at the SQL that is automatically generated.... Hmm, I would have been happy with: If you right-click and configure the tableadapter (from within the xsd file) accepting defaults all the way through then some SQL rather closer to my expectations is generated. You save the DataSet file and run again but still get the same error. However, if you search for this error on google (thanks Barry) you will find that setting the Gridview column for the primary key to be '''readOnly=false''' this resolves the error. At this point we have a TableAdapter working with a GridView. Its a shame that I couldn't leave out the steps above - but then I guess there would be no point to this article :-) To summarise, the TableAdapters work well but are let down by the default SQL generation. For all the discussion about SQL above I didn't have to hand craft any SQL statements to get this to work. But I did have to run through the configure wizard to generate useful SQL. The ReadOnly parameter is a default of the GridView, but still you would expect the two to work together better than they do. 12/7/2006 http://www.geekzilla.co.uk/viewF9581DAE-CCF8-49FF-844C-7498603E0005.htm Could not write to output file ... The directory name is invalid http://www.geekzilla.co.uk/view2C696305-35CB-4396-888D-7459CED5114C.htm Could not write to output file ... The directory name is invalid Recently had a problem deploying an app to a fresh 2003 server. Basically, the application wouldn't start, instead we recieved an error stating that the compiler couldn't write to the '''"Temporary ASP.NET Files"''' folder because the path was invalid. Eventually I tracked down the resolution : http://support.microsoft.com/default.aspx?scid=kb;en-us;825791 Cause The system TEMP and TMP variables point to a folder that does not exist. The compiler generates temporary files in the folder where the TEMP and the TMP variables point to before the files are copied to the Temporary ASP.NET Files folder. However, the folder where the system variables point to is deleted when you restart the computer. Therefore, the compiler cannot generate the temporary files. Resolution * Create a temporary folder under %Systemroot%, and then name it Temp. * Grant full permissions on the Temp folder to the '''NETWORK SERVICE''' user account. * Right-click My Computer, and then click Properties. * On the Advanced tab, click '''Environment Variables'''. * Select the TEMP variable under System variables, and then click Edit. * Type '''%SystemRoot%\TEMP''' in the Variable Value box, and then click OK. * Repeat last two steps to edit the TMP variable. Click OK two times. * Click Start, and then click Run. * To reset Internet Information Services (IIS), type iisreset on the command prompt. Note If the error message that is mentioned in the "Symptoms" section of this article persists, restart the computer. 7/7/2006 http://www.geekzilla.co.uk/view2C696305-35CB-4396-888D-7459CED5114C.htm Intellisence not working in web.config? http://www.geekzilla.co.uk/viewED8AD2FE-66D4-4BA9-822D-17A5E89F5A8D.htm Intellisence not working in web.config? Visual Studio 2005 has an interesting "feature" where Intellisence will not pop up when you're editing a web.config file. Annoying eh? Well, I found that removing the '''namespace''' from the '''configuration''' tag kicks it all back into life. Change the following line to 28/6/2006 http://www.geekzilla.co.uk/viewED8AD2FE-66D4-4BA9-822D-17A5E89F5A8D.htm Changing the password rules for Forms Authentication http://www.geekzilla.co.uk/viewBD8CFE61-E9B7-432B-8672-089E4962A52F.htm Changing the password rules for Forms Authentication An annoying feature of the forms authentication controls shipped with VS2005 is that it forces users to enter non-alphanumberic characters in their passwords by default.. e.g. password would have to be password! Fortunately, this option can be turned off by adding a membership provider section to your web.config The following setting controls the non-alphanumeric.. Below is an example of what you need to add to the '''<system.web>''' section 28/6/2006 http://www.geekzilla.co.uk/viewBD8CFE61-E9B7-432B-8672-089E4962A52F.htm Stopping simultaneous logins (Forms Authentication) http://www.geekzilla.co.uk/view733B7360-8C6C-4256-8EDC-026333750271.htm Stopping simultaneous logins (Forms Authentication) The following code (called from a page load) will bump off users who are logged in when someone else logs in with the same credentials. #c#} 27/6/2006 http://www.geekzilla.co.uk/view733B7360-8C6C-4256-8EDC-026333750271.htm Enabling HttpGet and HttpPost for web services http://www.geekzilla.co.uk/viewD5D13AF7-0E86-46F2-A954-F789132A6B5F.htm Enabling HttpGet and HttpPost for web services If your web application needs to accept incoming webservice method requests based on the '''GET''' and '''POST''' protocols then add the following lines to your ''web.config'' file. #h#</configuration> 24/6/2006 http://www.geekzilla.co.uk/viewD5D13AF7-0E86-46F2-A954-F789132A6B5F.htm EasyHTTP http://www.geekzilla.co.uk/viewB5BAB652-EBA2-44F8-8F30-0588E092873A.htm EasyHTTP EasyHTTP is a simple class which exposes the HTTP functionality of .NET as a number of simpler methods. #c#} 20/6/2006 http://www.geekzilla.co.uk/viewB5BAB652-EBA2-44F8-8F30-0588E092873A.htm Updating Foreign keys in a GridView http://www.geekzilla.co.uk/viewD7E7F40C-85F7-47D8-89DE-0FB5F7AFAAE5.htm Updating Foreign keys in a GridView A GridView generally shows and allows the user to update rows in a database. They are easy to set up until the values that you want to update is a foreign key. Its not obvious how to send the appropriate value back to the database or how to limit input to valid values (from the foreign key table). The solution to this is pleasingly simple... You simply need to add an asp:Dropdown control that takes its values from the foreign key table and bind the value of this as you would have done an input box. The code is shown below, the example assumes that the grid shows 'Person' records referring to a 'Job' table: #h#SelectCommand="spSelJobs" SelectCommandType="StoredProcedure"></asp:SqlDataSource> 20/6/2006 http://www.geekzilla.co.uk/viewD7E7F40C-85F7-47D8-89DE-0FB5F7AFAAE5.htm Garmin and Google Maps http://www.geekzilla.co.uk/view9B172E45-36EF-4655-91D3-CC0D3CE1B3E6.htm Garmin and Google Maps The bought a Garmin Forerunner recently which is a really cool piece of kit but the maps that come with it are very poor. Google maps has an API that allows you to integrate these rich maps into your own web applications. Garmin has the option to export your training history as an XML file. This XML file contains not just Latitude and Longitude points but also your heart rate, the time, elevation and what you were doing (i.e. cycling or running). From these you can work out more details such as how steep the hill was , how fast you were running and how hard your heart was pumping. Google provides a well documented API largely in Javascript. The current site, just shows a list of bike rides from the GPS XML extract and plots the ride on the map. It animates the ride by overlaying a small section of the ride in red and using setTimeout in a loop to keep it moving. Some of the key aspects are explained below... A reference to the google maps API script is included as described in the documentation. A map is created, on the server the width and height of the map is calculated (by looking at east/west-most and north/south-most points) and the javascript created to ensure that the map is centred and zoomed appropriately. The zoom model is a logarithmic one and I had to do a little relunctant maths to create this function. The source javascript shows an array of GLatLng objects. These are google map representations of a point on a map. The map objects addOverlay method is called to add a GPolyline object (a line) to the line. The animation is acheived by creating a GPolyline from a few points at a time. The GPolyline is then removed and replaced a bit further along the ride (which is basically an array). 19/6/2006 http://www.geekzilla.co.uk/view9B172E45-36EF-4655-91D3-CC0D3CE1B3E6.htm Missing VS2005 Templates http://www.geekzilla.co.uk/viewCA97A7D8-E9B9-49A8-BE1F-1CE923F000D4.htm Missing VS2005 Templates If you are having problems with missing VS2005 templates, then the following command run from the VS2005 command prompt may resolve your problems. devenv /installvstemplates 19/6/2006 http://www.geekzilla.co.uk/viewCA97A7D8-E9B9-49A8-BE1F-1CE923F000D4.htm Perform actions before a row is deleted from a GridView or a DetailsView http://www.geekzilla.co.uk/viewD38381DA-51AF-43BA-A199-36C6F3D58708.htm Perform actions before a row is deleted from a GridView or a DetailsView I'm a big fan of '''caching''' objects on the web server, really saves loads of unneccessary trips to SQL Server and those precious resources. In a recent project I built some administration screens to change the configuration of my site, as it happens this data was cached on the server for 8 hours at a time. Rather than let the cache expire for the changes to be picked up I leveraged a feature of the '''GridView''' and '''DetailsView''' controls I was using, to clear the cache on a DELETE or INSERT by simply using the '''RowDeleting''' Event on the '''GridView''' and the '''ItemInserting''' on the '''DetailsView'''. Here's the code: Using the '''RowIndex''' property of the '''GridViewDeleteEventArgs''', you can then access the row that you're just about to delete. Here I have a hidden field that holds a key suffix to a cached object. This isn't a key in my '''GridView''' or I would have used the DataKeys property. When I need to insert some data via the '''DetailsView''' I used the following code on the '''ItemInserting''' event. Here I'm grabbing the key suffix from a dropdown list in the '''DetailsView'''. I clear the cache and perform the INSERT to the database. This will ensure that the latest data is loaded and cached for the next request. 14/6/2006 http://www.geekzilla.co.uk/viewD38381DA-51AF-43BA-A199-36C6F3D58708.htm Select a row in an asp:GridView without using a Select Command http://www.geekzilla.co.uk/view9FC28EE6-ACB0-4F51-BFE4-38B0B10134D5.htm Select a row in an asp:GridView without using a Select Command ASP.Net's GridViews can be quite useful, but beware of binding them to huge datasets as this has an overhead on the ViewState. Often you'll want to display a number of columns on each line and row space becomes an issue. What's worse is you then have to create a '''SELECT''' command button to be able to access that line's data. Use the following code on the event OnRowDataBound to eliminate the need for the '''SELECT''' command field and save yourself some valuable space. Here is the '''HTML''' to create a GridView, I'm displaying a list of people, and the key for each record is the '''PERSON_ID'''. The key event to note is the OnRowDataBound, use the following code to create '''SELECT''' functionality on the row. Each row will then behave like a link, and when you select one it can drive the behavior of another control(s) on your page, possibly a DetailsView allowing you to INSERT a complete record to the database. 14/6/2006 http://www.geekzilla.co.uk/view9FC28EE6-ACB0-4F51-BFE4-38B0B10134D5.htm Error in Line 3? http://www.geekzilla.co.uk/view24F4A0DD-5DFE-42C8-B05F-B2415000AEF2.htm Error in line 3 Some websites report an error in line 3 when using the asp.net controls such as login. We recently tracked this error down on one of our sites to the use of custom HttpHandlers. All requests to anything other than *.aspx were routing through our own handler.. Adding the following to the web.config fixed the problem 13/6/2006 http://www.geekzilla.co.uk/view24F4A0DD-5DFE-42C8-B05F-B2415000AEF2.htm