Making a Dynamic Data Scaffold Table Readonly

So couple of days ago I talked about the new ADO.NET Entity Data Model. The Entity Data Model sometimes also referred to as the Entity Framework can also be used with the new Scaffolding feature that’s available in .NET 3.5 SP1. Scaffolding allows the run-time engine to build a CRUD (Create, Read, Update, Delete) operation system for a given model. However, it is often times useful to include a model just for viewing purposes not for editing or deleting – which is a behavior that comes in by default with the scaffold operation. In order to to that you can simply edit the Global.asax file and before the default routing code add the following lines of code:

#region Readonly tables
var visibleTables = from t in MetaModel.Default.Tables
where t.Scaffold == true
select t;

var readOnlyTables = new StringBuilder();
foreach( var table in visibleTables ) {
var isReadOnly = table.Attributes.OfType<ReadOnlyAttribute>().
DefaultIfEmpty( new ReadOnlyAttribute( false ) ).
FirstOrDefault();

if( isReadOnly.IsReadOnly )
readOnlyTables.Append( table.Name + "|" );
}

routes.Add( new DynamicDataRoute( "{table}/{action}.aspx" ) {
Constraints = new RouteValueDictionary( new
{
action = "Edit|Insert",
table = readOnlyTables.ToString().Substring( 0, readOnlyTables.Length - 1 )
} ),
ViewName = "Details",
Model = model
} );
#endregion

Basically using LINQ this code goes through all the tables in the MetaModel (which holds all the models in a given namespace) and looks for the [ReadOnly(true)] attribute for each of the classes. If there’s a table found with the ReadOnly attribute the Edit/Delete operation is re-routed to the View Page (Routing is also a new technique that’s available in .NET 3.5 SP1).

Some excerpts of this code taken from Stephen Naughton’s blog.

Nominate Subversion


If you use Subversion, please take a moment to nominate it for the Community Choice Awards. I think it’s one of the best open source products out there.

How does ADO.NET Entity Model Assign Primary Keys?

If you’ve used the ADO.NET Entity Data Model to generate some models from your database schemas you’ll have noticed that sometimes ADO.NET assigns primary keys that does not necessarily correlate with your database schema. This is specially true if you are pulling from a view that has several joins. For instance, notice in this model the Term, the SrsNumber and the CatalogNumber is marked as the primary keys (Course happens to be a View in this case):

course

But in reality, the actual table the view pulls from only has Term and SrsNumber marked as the primary keys. So what’s going on? Turns out the ADO.NET Entity Data Model assigns primary keys to all non-null columns.

If you have the freedom to correct this in the database schema then that’s one solution to mark columns nullable otherwise you’ll have to manually adjust the CSDL (Conceptual Schema Definition Language) file manually. More on that tomorrow.

Internet Knowledge Society

“Internet knowledge” can be scary. It’s not about how much you know about the internet, but rather the knowledge you gather using the internet.

Internet knowledge tends to give the impression of knowledge about a certain topic, which is one of the reasons why Wikipedia is so successful. For instance, Wikipedia explains Kleene star in less than one page. Yet anyone who has taken a class in complexity theory must have felt those sleepless nights on K* problems–the problems so elegant and simple yet so hard to come up with a solution. In most cases reading from the internet only give you a very basic high level overview of a certain topic. It almost seems like common sense when I say this, but people don’t seem to realize that when they learn about Tuberculosis in under five minutes that their knowledge is basic.

This has given birth to a slew of so-called internet engineers. Their knowledge about software development starts from reading the internet.

Google plays a huge role in this. The Google search engine is simply amazing. If a web developer is stuck he/she issues a search gets back bunch of code, integrates it somehow to his/her problem and there you have things start working. That’s an issue. Developers don’t have the basic understanding, concepts like inheritance, and polymorphism seems like alienated words-yet they are using it everyday in the .NET framework. So I fear this has spawned a culture of believe that we are an educated society.

No knowledge is better than some knowledge. Yes, I didn’t type that incorrectly, I did mean to say no knowledge is better than some knowledge. If you don’t have any knowledge about something it’s very easy to accept it. But if you have some knowledge, then it’s really hard to gaze how much you know. Because relatively, from the point you didn’t know anything – to the point you know something, you actually know infinitely more, even though the knowledge may be 5% of the actual topic.

So what does that mean? Don’t use the internet, don’t use Wikipedia, don’t use Google? No, not at all. Absolutely use these tools, these tools help shape our lives but keep in mind the breath of knowledge you’ve gained. That’s the key.

How to check if Integrated Windows Authentication is available?

If you’ve ever worked on an intranet site, you often want to know, programmatically, if a client that’s accessing your website has the ability to automatically login to your site (Integrated Windows Authentication). With Integration Windows Authentication, Windows can basically send (as a HTTP header) the currently “logged on” username. So your application can access this LOGON_USER HTTP header and go from there.

I won’t get into the details of how to setup integrated windows authentication, but basically the idea is you go into IIS and for a given resource (a folder or a file) on your site you change the directory security to Integrated Windows Authentication. Once this is done, when a client visits your local site (the definition of local depends on the gateway or group policy), IE switches to the “intranet site” profile which allows the automatic authentication. That’s the broad picture. But unfortunately, if the same users visits that same website from another location, say from their home, they will end up getting the ugly NTLM authentication box – and most of the times they don’t know what to do. Partly because their experience has changed, at work they were simply “logged in” without doing anything and now they have to login and often times need to prefix their username with domainusername format. That’s not good.

So it’s useful to be able to find out programmatically if integrated windows authentication is available, if it is then you simply login using the integration authentication, otherwise you provide the user with a clean and simple forms authentication system. So let’s start with some JavaScript code:

var autoLogin=true;

try {
	var dom = new ActiveXObject("Msxml2.DOMDocument");
		dom.async=false;
		dom.load("ntlm/spacer.gif");
	}
	catch(e) {
		autoLogin=false;
	}
}

The code makes an AJAX call to a resource that you know is locked with integrated windows security. If the AJAX calls succeeds you know that your client has integrated authentication get to the resource. If it does not you know something’s wrong, either they are using FireFox, or perhaps they are at home, whatever the case, your client cannot get to the resource without authentication. This is great, but we don’t want the user to see an error message when the AJAX call fails so we wrap it around a try/catch block. The catch block essentially sets the autoLogin=false because something did not work out. That’s it – that’s a nifty little trick to check if your users can use integrated windows authentication.

AJAX Live Binding in .NET 3.5

One of the seminars at TechEd this year was on the new Live Binding method that Microsoft announced for pure AJAX applications. In the past working with pure AJAX applications (not using the update panel, think of XMLHTTP), required that you do a lot of DOM manipulations, or have a server side controller that generates the HTML which is then plugged into the client HTML stream. The first option becomes extremely tedious, hard to manage and is very error prone. The latter method works, but requires that you mix your logic and UI. While it may be possible to separate the two, it still does not make sense why the server has to take the load of structuring HTML documents when it can be busy doing far more important things. So neither option is geared toward businesses. Which is why Microsoft implemented the new Live Binding technique.

Live Binding works by binding a regular HTML page to a web service using jQuery, and the Microsoft AJAX Framework. Let’s look at an example:

The first step is to create a HTML template page, which is nothing but a regular HTML page with special markup where the active binding data is going to change, in this case {{Username}}, {{Title}}, and {{GroupMemberships}}

HTML Template

<table border="1" class="template-table" cellpadding="5">
	<thead>
		<tr>
			<th>Username</th>
			<th>Title</th>
			<th>Description</th>
		</tr>
	</thead>
	<tbody id="template" class="sys-template">
		<tr class="{{$index%2?'odd':'even'}}">
			<td>{{ Username }}</td>
			<td>{{ Title }}</td>
			<td>{{ GroupMemberships }}</td>
		</tr>
	</tbody>
</table>

Secondly, we need a web service that will return the data to the template. In this case I am querying our ActiveDirectory using the ActiveDirectory data access layer for all users in the Test OU.

Web Service

[ScriptService]
public class Service1: WebService
{

	[WebMethod]
	public List<Law.Entity.User> HelloWorld() {
		Law.Dal.ActiveDirectoryDal ad = new Law.Dal.ActiveDirectoryDal();
		List<Law.Entity.User> users = ad.GetUsersByOrganizationalUnit( Law.Utils.Enumeration.ADConnections.Test );
		return users;
	}
}

Okay, now that we have the template and data service provider, we are ready to plug the template with the web service. With just few more lines of jQuery, and Microsoft AJAX JavaScript code we can accomplish that:

Actual Binding using jQuery and Microsoft AJAX

$(document).ready(function() {
	var dataContext = $create(Sys.Data.DataContext,
	{
		serviceUri: "/ajax/service/service1.asmx"
	});

	var template = $create(Sys.UI.DataView,
	{
		autoFetch: true,
		dataProvider: dataContext,
		fetchOperation: "HelloWorld",
		fetchParameters: {}
	},
	null,
	null,
	$get("template"))
});

Let’s talk through this, to see what is going on. First notice we are using the standard jQuery document ready notation $(document).ready to run some javascript when the document is ready. The first thing is to create a DataContext, a DataContext is basically an object that talks to a web service, in this case I’ve set the serviceUri to the web service we discussed earlier.

The second and the last step is to create a DataView. A DataView uses a DataContext to populate a template – that’s it. Setting the autoFetch to true just says that whenever we hit that line of code start fetching the data, the dataProvider, simply points to the dataContext object and the fetchOperation basically says which web service method to call in the dataContext. And finally, the last statement $get(“template”) is a shorter form of document.getElementById which returns a JavaScript DOM object to the Id.

With that in place, we can run the code and it should display users from the ActiveDirectory, using a web services and live binding.

May 25th, 2009 (Updates)

One of the questions that I have seen come up often is what JavaScript libraries are required in order for this to work. Here’s a list of all the JS files and where you can download them from:

MicrosoftAjax.debug.js
MicrosoftAjaxAdoNet.debug.js
MicrosoftAjaxTemplates.debug.js
jquery-1.3.2.min.js

jQuery can be download from jQuery.com. The MicrosoftAjax libraries can be downloaded from CodePlex