Adding Web Service to ASP.NET Website

No Gravatar

A web service does not have to stand alone. One can be easily added to an existing asp.net website. In visual studio, just add a new item (web service) to your project. Check the checkbox for code in separate file in the add item dialog. Two files are created, the asmx, which goes in the project directory (or any subdirectory you wish), and the code behind file which is put in the app_code directory.
adding web service in vs
You can do this manually, if you like, with the same procedure – just put the asmx file in your site directory, and the code file in app_code.

Aria support for AutoComplete Menu

No Gravatar

We have the following widget on our page:
It looks like a combobox widget with autocomplete support but actually is a list of links that when pressed takes the user to the link location. In other words, the items in the popup list are actual anchor links that work. There is no selection process, no selected value or selected item since the only purpose of the widget is to provide links. The widget consists of the standard combobox controls: textbox, dropdown image button, and a <ul> marked up list of links, in that order in the DOM. I want to make sure that it is accessible by WCAG standards.
All of the HTML is to spec, and the only accessiblity concerns I have are about making sure a screen reader user understands the relationship between the DOM elements of the widget. That is to say, the user must know that the textbox value controls the filtering of the list, etc. The obvious choice for this was the ARIA standard. Despite the fact that ARIA is at its best and most necessary when non-native elements (such as div or span) are being used, and in my widget I am using focusable native elements such as <a>, <input>, <ul>, nevertheless I think some sort of programmatic determination is necessary to connect the dots.
The question is what role should the widget have. The first logical choice would have been combobox, and in fact, in this webaim mailing list archive about the issue many seemed to feel that combobox was the way to go. But, unless I hear from an ARIA expert to the contrary, I think this is really a menu. The reasoning is as follows: A combobox will certainly aid in relating the textbox to the autocomplete list, yet the nature of a combobox is selection, that is it is selectable, and has a selected value or values. But my menu widget does not have any selectability. So, it seems that a menu role with a dropdown menu is the logical choice. The problem with that is that the menu role doesn’t seem to have any allowance for a filtering textbox to be associated with it. The most I could do was to give the list an aria-owns attribute with the id of the textbox in order to connect them minimally. Furthermore, I put a title attribute on the textbox with a very short blurb about what it does. The aria-owns attribute of the list also included the id of the dropdown image to be on the safe side. Please comment with any ideas you may have for my widget. here is the html:
<div style="z-index: 1000;"><div style="width: 118;border: solid 1px #D4D0C8"><input type="text" style="vertical-align: bottom;width: 100;border: 0;height: 16px" autocomplete="off" title="typing in the text box filters the list of links" id="AutoCompleteCombo1_txtAcc" aria-owns="AutoCompleteCombo1_listUl"><input type="image" border="0" style="vertical-align: middle;cursor:pointer;border:0;height: 18px;width: 14px;background:#F3F2E5" alt="open list of links" src="arrow.gif" aria-haspopup="true" onclick="return false;" id="AutoCompleteCombo1_mltDropDown" ></div><div style="background-color: rgb(255, 255, 255); display: none; overflow: auto; max-height: 150px; position: absolute; border: 1px solid rgb(212, 208, 200); width: auto;" class="autoCompleteList" tabindex="-1" ><ul aria-owns="AutoCompleteCombo1_txtAcc,AutoCompleteCombo1_mltDropDown" role="menu" ><li role="menuitem"><a href="http://google.com">first site</a></li><li role="menuitem"><a href="http://google.com">second site</a></li><li role="menuitem"><a href="http://google.com">third site</a></li></ul><input type="submit" style="float:left;background-color:Transparent;border: 0;" value="x" ></div></div>

RadioButtons in ListView Itemtemplate

No Gravatar

I’m not your everyday Microsfot basher, but gee wiz – how could they have gotten this wrong! If I put radio buttons in an itemtemplate,they will not be mutually exclusive, even if I assign them the same groupname. See this article about the bug for more details. What the heck are we supposed to do now – find a another quick and dirty workaround? Yes, we are, and here it is:
First, the code from the itemtemplate:

<ItemTemplate>
<tr id="Tr1" runat="server">
<td style="width:120px"><input type="radio" value='<%#Eval("id")%>' name="homepage" /></td>
</tr>
</ItemTemplate>

This code uses an html radio button with no runat=server tags, in order to prevent asp.net from messing with the name property. The rendered result will be alot of listview rows, each having a radio button for the group “homepage”, such that all of them are mutually exclusive. The value of each radio button is the dataitem generated id, such that each one has a unique value, and one which will be used in server side code to evaluate the checked radio button. The problem is how to get the checked radio value on the server side? On this particular form, the user is expected to update lots of info in the listview, sort of like a mini form. So, when he presses the save button, server code has to evaluate each of the listview items and update the database with its values. So here is how we do it for the radio button. In this example, the radio button indicates which item will be displayed on the home page (only one will be displayed).
Dim homepage As Integer = CInt(IIf(Request.Form("homepage") = id.ToString, 1, 0))
In the DB, I store a 0 for all items not displayed on the home page, and a 1 for the item which will be displayed on the home page. The request form object gives us the value of the checked radio button for the “homepage” group of buttons. The value, as you recall, is the id of the item at hand. So, I now have the id of the item which has to have a value of 1 in the db. I loop through all the listview items, and get a value of “homepage”, which is either a 0 or 1, depending on the id value of the radio group. Really simple.

IIS Application Pool Stops Working – Event Id 5059

No Gravatar

Running Windows 7 and IIS 7. All of a sudden my DefaultAppPool kept shutting down as soon as I started up any application using that pool. Found the following description in the event viewer for EventId 5059:

Application pool DefaultAppPool has been disabled. Windows Process Activation Service (WAS) encountered a failure when it started a worker process to serve the application pool.

Found a comment from poster vDugar at http://technet.microsoft.com/en-us/library/cc735276%28WS.10%29.aspx and it turned out I had the same problem. My app pool is configured to use my windows identity, and of course the password expired at some point and I changed it, and how in heck was I supposed to remember to change it in the app pool. Thanks to vDugar for the save.

CreateResourceBasedLiteralControl Error

No Gravatar

Got this nasty error when I had to import an old solution to team system. The masterpage seemed to be the culprit from the error description. Did the usual clean solution bit to get rid of old dlls, but nothing I found on the internet worked. Turns out I had a reference to a certain dll in my project, for example’s sake it was version 3.8.3 of the dll, and in the web config the dll was referenced as version 3.7.3. I had both versions on my computer so there was no “assembly not found” error, yet the spooky CreateResourceBasedLiteralControl error did pop up as a result. Updated the web config and everything was fine after that.

Quicktime Embed Bgcolor Attribute

No Gravatar

This page detailing quicktime embed attributes gives an example of using a hex color to give a background player to any unused space in the player area. Just wanted to let you know you can use html colors with the hash symbol, such as:
<embed bgcolor="#FDFBF4" ...

Embedding Image from LinkedResource in Net.Mail

No Gravatar

I just love it when you find a great solution someone posted to a problem you just can’t figure out. I was embedding an image from a stream in a system.net.mail message. It just wouldn’t appear in the message. Then I found this post from niaherC. Thanks for sharing the solution. What I was missing was to use stream.seek method to get to the beginning of the stream. Anyway, here is the final code I am using:
Dim image() As Byte = (some image in a byte array)
Dim contentType As String = "image/jpeg"
Dim s As Stream = New MemoryStream(image)
s.Seek(0, SeekOrigin.Begin)
Dim imageResource As New LinkedResource(s, contentType)
imageResource.ContentId = "card"
Dim view As AlternateView = AlternateView.CreateAlternateViewFromString("Here is an embedded image.<img src=cid:card>", Nothing, "text/html")
view.LinkedResources.Add(imageResource)
Mail.SendMail(address, "blah", "blahblah", view)
s.Close()

This code embeds an image in the email itself instead of attaching it.

Migrating to IIS7 with WCF

No Gravatar

Just installed windows 7. Web sites didn’t work. I got http error 500.22. Saw posts that I had to change the application pool (iis > yoursite > advanced settings > application pool) from defaultapppool to classic .net apppool. Then the error became http error 404.17 for my wcf. Tried adding system.webserver section to the web.config with all the handlers junk as in this post about adding webserver section, but it didn’t work. The I found this great post about installing wcf handlers. Ran servicemodelreg -i from the directory C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation and it worked like a charm.

Cross Browser CSS Text Overflow

No Gravatar

Just found a great solution for text overflow which works cross-browser. Any element which needs to have this styling should have the following class:
.ellipsis
{
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
-ms-text-overflow: ellipsis;
-moz-binding: url("../ellipsis-xbl.xml#ellipsis");
white-space: nowrap;
overflow: hidden;
}

This class will show three dots (ellipsis) when text spills out of its container. You might have to declare a width on the element in question. I found this code in a number of places so I won’t bother linking you to them. For FireFox, you will need the xml file referred to in the CSS code.The xml file needs to exists on your site with the following code:
<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://www.mozilla.org/xbl" xmlns:xbl="http://www.mozilla.org/xbl" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="ellipsis">
<content>
<xul:window>
<xul:description crop="end" xbl:inherits="value=xbl:text">
<children/>
</xul:description>
</xul:window>
</content>
</binding>
</bindings>

The reason I am posting is simply to remind you to make sure that the path to the xml file in your css is correct – i.e. if your stylesheet is in a different folder, don’t forget to put the right amount of dots there, like I have in the css code above.

Cross Application Forms Authentication in Asp.Net

No Gravatar

Introduction

I just implemented forms authentication for two applications who had to share the same user (so that one user wouldn’t have to log in twice). Most of what I am going to write here is straightforward and can be found on other sites, yet I wanted to detail the process I went through because my implementation was slightly different than most other tutorials on the subject. Here are the major steps.

Web Config

The web.config file will contain the configuration for the forms authentication. Here is the code I used:
<authentication mode="Forms">
<forms loginUrl="Login.aspx" enableCrossAppRedirects="true" defaultUrl="Default.aspx" />
</authentication>
<machineKey validationKey="......"
decryptionKey="........" validation="SHA1"/>
<authorization>
<deny users="?" />
<allow users="*"/>
</authorization>

First off, you must specify the authentication mode to be Forms. Next, configure the loginurl and defaulturl, if needed. The defaulturl will throw the application to that url when a redirect url is not present. Loginurl is obvious, and optional (defaults to login.aspx). Also, I specified enableCrossAppRedirects to be true so that my second application could be accessed by the same user from the first app.
Next, add a machinekey element which is unique to the application. In the code I have provided, I did not paste my own keys, just …. (after all I don’t want amy of you accessing my apps). This means that to protect your app completely you must generate it yourself. This online generator from Peter Bromberg does the job nicely.
The reason we need the key to be unique is if there are two apps on the server and both are using forms authentication. In such a case, one app could access the other since they share a common user identity. It will also help us share the user identity between two apps that we do want to be able to access each other.
In the authorization element, I have specified that anonymous users cannot enter the app, meaning that they must be authenticated first. On the other hand I have specified that all users can use the app if they have been authenticated. You can also filter users with additional settings.
Ok. Now let’s see the code.

Custom Authentication

There are many ways of actually authenticating the user’s identity, usually validating credentials against a database. However, in my case, our organization uses a separate application to do that.
So, i wired my app with forms auth into the authentication app and out came a white rabbit.
What follows is the code where I actually authenticate the user. My app receives an encrypted key from the organizational authentication app and I won’t go into that.
Dim user As Integer = Authentication.Authenticate(Session, Request.Form, Response)
If user > -1 Then
FormsAuthentication.RedirectFromLoginPage(user.ToString, False)
End If

My Authentication.Authenticate method tests the encrypted key I receive (not relevant to all of you) and produces an integer if valid, or -1 if not. Once i see that the integer produced is not -1, I call the FormsAuthentication.RedirectFromLoginPage method from asp.net which actually causes the validation of the user, and that user can now access all of my pages (unless I specify otherwise).

The Second Application

The second application I want my user to be able to access is readily accessible to that user if I just do one thing in this second app. I simply have to copy and paste the exact same code from web.config of the first app into the web.config of the second app. Since they share the same validationkey and encryptionkey, the second app will recognize the user coming from the first app as a valid user identity and allow him to access all of its pages. That’s it!

Update: One weakness I have found and not been able to solve is to get this implementation to work one-way, that is to say the one app can generate authentication for the other, but not vice versa. The enableCrossAppRedirects attribute does not prevent this. Once the first app gives authentication in its own app then the user can simply open a new tab and access the second app. In my case, we have a display site and an admin site. I want the admin user to access the display site (which also requires authentication) but not a display user to access the admin site. In the meantime I have hand coded to block users from entering the admin site unless they have the right identity, but I wish that I could find a built in configuration for this. If anyone has an idea please comment.

Update: I have found a fix to the above problem. In the Global.asax code behind in the session_start event, I added:
FormsAuthentication.SignOut()
FormsAuthentication.RedirectToLoginPage("signout=1")

This made sure that at each session start the previous authentication would be removed. You have to redirect also to remove the browser cookie. Also, I had to add a query string of “signout” (it could be anything) to avoid an infinite recursion when the user would first request the login page. The downside of this approach is that the authentication session is only good for the server session. Not persistent. No choice. If anyone can comment about this approach I would appreciate it.

FireStats icon ‏מריץ FireStats‏