Showing posts with label ASP.NET. Show all posts
Showing posts with label ASP.NET. Show all posts

Thursday, June 12, 2008

Link: Databinding PDFs in ASP.NET

An interesting article about generating PDFs in .NET using iTextSharp, a port of the iText open source Java library written entirely in C# for the .NET platform. And incidentally, elsewhere db4objects releases its Sharpen Java to C# tool for free. It converts your Java source code into C#!

Friday, June 6, 2008

Links for Work: ASP.NETand stuff

I've been busy at work, mostly with taking out the budgeting functionalities in our HR-based Training module and turning it into a standalone web application. This gave me a few interesting architectural challenges as I decoupled the software, and later reintegrated it back into the main product in a more modular approach. Basically, we wanted to reuse the Training module's budgeting component in our Recruitment module.

This exercise also let me play with some of the newer technologies, like LINQ and ASP.NET 3.5 which have somehow fueled my obsession with things like code base reduction, doing things declaratively with ASP.NET, and a new-found preoccupation with performance which in a lot of cases have lead me down the dark path of premature optimization. Anyway, many interesting lessons learnt, and a few more days and I'll be off this project. Here are some interesting links which I've collected:
Asynchronous ASP.NET pages
Using JSON with ASP.NET 3.5
Self Sorting GridView with LINQ Expression Trees
7 tricks to simplify your programs with LINQ
Loading and Executing JavaScript Files From JavaScript, ASP.NET AJAX
Try-catching in a single line of code

Previous work-related posts here on this blog:
Partial rendering without UpdatePanel
Detecting a BLOB's MIME type

Friday, May 16, 2008

Partial rendering without UpdatePanel

Performance on the Visual Studio development web server was slower than I expected. I don't have any benchmarks, but I thought the boss' initial yawn when I tried to show him the prototype was sufficient. So, after not getting much perceived performance gain even with the LINQ queries all tightened up, I stumbled onto the AJAX-ed UI templating sans Upload Panel technique as Scott Guthrie posted on his blog about some time ago. I thought this technique was quite suited to my application since it used a lot of custom user controls. So, I put it in and it worked. It felt a little faster than before.

Along the way, I discovered that I couldn't implement PageMethods in the user control, but that I could get the user control to call PageMethods defined in the containing page. So in my best effort not to have my logic strewn all over the place, I put the PageMethod in a base page which each containing webpage would inherit from. I didn't want to use web services. Of course, you wouldn't understand any of this unless you read Scott's post.

In any case, I was pleasantly surprised to find out that ASP.NET 3.5 performance, particularly with LINQ was not as bad as I had experienced after deploying to a staging server. A case of premature optimization, that's all.

Monday, May 5, 2008

Links

Have ASP.NET WebMethod called from jQuery; Create an ASP.NET 3.5 AJAX control extender; and, Dynamic Text Replacement with JavaScript and C# ASP.NET.

On my current preoccupation with LINQ programming, and more specifically, my current problem involving dynamic querying, these came up rather interesting - although I ended up denormalizing the data structures out of the dynamic querying: dynamic methods via LINQ expressions; Using an extension method to combine query predicates; and, dynamic queries and LINQ expressions.

From the Three Helpful JavaScript Libraries article, Fluently (for method chainability), MOP JS (for metaprogramming), and Collection JS (for collections and stuff).

And finally, some JavaScript miscellania: Running Java in JavaScript; and, a (partial, canvas-dependent implementation of) Wolfenstein 3D in JS.

Monday, December 3, 2007

Detecting a BLOB's MIME type

This post describes how easy it was for me to include a third-party class library into my existing ASP.NET application, to determine the MIME type of BLOB data.

We used to carry a crappy ASP.NET application as part of our software solutions offering. Though we no longer sell it, there remains one customer installation for which we were obliged to support with bug-fixes. One problem that surfaced was file uploads which accepted only image files. To be accurate, the application accepted user file uploads of all kinds, but for some reason, each of these uploaded files, when downloaded became either a jpeg or gif.

Upon inspection, I saw that when the file is uploaded and stored in a BLOB column, the file type information is not stored along with it. Worse still, jpeg and gif file extensions were just about randomly appended on the download page. Yep, WTF.

My task was to modify the program so that each file download was appended with the right file extension according to its MIME type. This way, the user can use pre-installed viewer softwares to download and view the files e.g. using Adobe Acrobat when a PDF link is clicked. Deciding only to change the download page, with inline C# script blocks (no code-behind), I found a C# library (Winista.Mime) which determined MIME types by analyzing binary data. Sweet.

All I needed to do to start using this wonderful library was to download the project, build it and put the resulting dll in the bin folder of my ASP.NET application. Then, I referenced the library from my download ASPX with this import directive:


<%@ Import Namespace="Winista.Mime" %>

And, in the download portion of the code (which happens to be in the Page_Load method), I added the right file extension to the Content-Disposition header:

...
Response.AddHeader("Content-Disposition",
"attachment; filename=file." + GetExtension(theBlob) + "; " +
"size=" + theBlob.Length.ToString());
...

You'll notice this piece of code makes a call to a method named GetExtension(). This is the only place where the library is used. Here it is:

private bool GetExtension(byte[] data)
{
MimeTypes mimeTypes =
new MimeTypes(Request.MapPath("mime-types.xml"));
MimeType mimeType =
mimeTypes.GetMimeType(Winista.Mime.SupportUtil.ToSByteArray(data));
return mimeType.Extensions[0];
}

That's it, short and simple. I forgot to mention that the library stores patterns for each MIME type in an XML file called mime-types.xml, which you'll need to put into the same folder.

If you need to add a class library to your ASP.NET application quickly (no recompiling your ASP.NET application), you can follow the steps described above. If the library you're building targets a different version of .NET, just put it in a bin folder in a virtual directory that has been set to the appropriate version of .NET, and which is accessible from the current application. This also means you'll need to replace the current webpage with a new one residing in the target virtual directory.

Also, although not really related, I previously wrote about using client-side scripting to hack in file upload functionality for a closed-source ASP.NET application (another submodule in the software described in this post):
Using unobtrusive JavaScripts to extend an ASP.NET product
Bad way to extend an ASP.NET product - the details
Bad way to extend an ASP.NET product

Friday, November 30, 2007

Not exactly mainstream ASP.NET

Here are some interesting ASP.NET links I collected in the past two months. They're all really clever - the best alternative I can think of in place of hacky - and, so really cool, I've been dying to put them to use somewhere in a project at work. Thank God my busy schedule has kept me from doing just that. These solutions aren't exactly mainstream...

Thursday, November 15, 2007

Using unobtrusive JavaScripts to extend an ASP.NET product

I previously blogged about using JavaScript to extend the functionality of a closed source ASP.NET product. Now, using similar client-side methods, we're also rolling out bugfixes. This post is about how we used unobtrusive JavaScripts to make the process easier.

The story so far: after falling out with our partner, we've stopped receiving support for a module we sold as part of our solution. We've got access to the ASPX files but not the C# code-behind or business classes. So, we went with JavaScript hacking to dynamically generate iframe containers for our new file upload functionality. Sometime last week, we successfully deployed the customization. The customer has since logged several presentation layer bugs that we now needed to fix e.g. figures not adding up correctly etc.

Although we're able to change markup within the ASPX files, we were careful to introduce changes unobtrusively (in the conventional sense, as applied to JavaScript code, and also by principal in regards to the existing module, so we won't in any way risk breaking an application that's running live). I found rules like the seven in Chris Heilmann's recent post (read also the article) provided for very good best practice guidelines towards our goal.

Area of Impact
Firstly, we minimized change to the existing code base by consolidating all changes into a single JavaScript file, customization.js, which is then loaded dynamically by every webpage in the application.

Assumptions
We started development with assumptions based on existing project requirements i.e. Internet Explorer is the only targeted implementation browser, and JavaScript is required etc. So, we didn't need to worry about non-standard input devices and browsers other than a JScript-enabled IE. This really helped.

Hooks and Relationships
One of the bugfixes required me to retrieve numbers from Label controls in each row of a databound GridView, total them, and display the result in a TextBox control. Upon inspection of the ASP.NET generated HTML, I noticed that the resulting Label control ClientIDs looked like grdMain__ctl3_lblAmount, grdMain__ctl4_lblAmount etc. The TextBox was simpler to access, straight up by its ID. I wrote the DoSum() method to hook onto the HTML elements by searching for spans ids that matched the pattern.


var Customization = {
...
DoSum: function() {
var total = 0;
if(document.getElementById &&
document.getElementsByTagName) {

var labels =
document.getElementsByTagName("span");

var totalTextField =
document.getElementById("txtTotal");

if(labels && totalArea) {
for(var i in labels) {

// Check if the span has an id
// Check if the span's id matches
// Check if the span's text is a number
if(labels[i].id &&
labels[i].id.indexOf("lblAmount")>0 &&
!isNaN(labels[i].innerText)) {

total += parseFloat(labels[i].innerText);
}
}

// write to the text field
totalTextField.value = total;
}
}
}
...
}
...
(function(){
...
Customization.DoSum();
})();


One other enhancement required us to change a form TextField into a DropDownList. I used methods similar to the above to find the TextFields and then, appended a select element to the innerHTML property of the TextField's parent node, and changed the display style property of the TextField to "none". The drop-down list's onchange event handler then updates the invisible TextField accordingly. The possibilities for what you can do are endless, and with unobtrusive JavaScripts patterns, they're a lot more manageable.

Future Development and Maintenance
Concerning further development, we made sure our code is readable, unambiguous and complete with concise comments so we could work with it easily in the future. We encapsulated our code into objects, namespaces and anonymous functions to avoid naming conflicts with both existing and future code.

This also hid the details of our implementation code from the outside world, though in reality, being the sole vendors in this case we didn't have to worry about third party developers.

More reading on unobtrusive JavaScript:
Behavioural Separation, and
The Behavioural Layer: Using JavaScript for Good, not Evil (both by Jeremy Keith)

Monday, October 29, 2007

SubSonic on target with Microsoft's ASP.NET MVC Framework

Last month's link to Scott Guthrie's announcement of Microsoft's ASP.NET MVC framework garnered a brief comment on the viability of using SubSonic as data layer in the upcoming web framework. It would be like using ActiveRecord with MonoRail. It's quite obvious (well in retrospect, anyway) how well SubSonic plugs into that hole. A few weeks later, Rob Conery, the creator of SubSonic is hired by Microsoft to work on SubSonic fulltime. Wow. It's time to get the team up to date on all this.

Recent interesting weblinks about SubSonic:
How MVC, jQuery, and SubSonic Will Make You Smile
5 Reasons why SubSonic is Better than Sliced Bread

Wednesday, October 24, 2007

Model-View-Presenter in C#

Found this blog post on implementing Model-View-Presenter (MVP) in C#.

While my main need has been testability, the post shows another advantage of separating model and view layers. It's really easy to reuse the model with different presentation technologies. The example is done with both ASP.NET and Win Forms UIs!

Don't know how to start moving existing software into these model-view separated patterns? Which framework to use? Microsoft's ASP.NET MVC Framework still a long way off? I guess that means we're in the same boat. I've got a few custom and smallish webapps in the pipeline that might be good candidates to experiment with this kind of stuff. Might try some of the ideas in the post, just to start me off in what looks to be the right direction.

Previously:
Model-View separated JavaScripts

Wednesday, October 17, 2007

Bad way to extend an ASP.NET product - the details

Last week I posted about extending an ASP.NET product without changing the code-behind. You'll need read it to make sense of this post. That was the motivation, now here's the technical details, as promised.

The requirements, and as you read on, keep in mind that I have no access to the code-behinds:

We have a document with an approval workflow. We need to extend this document with attachments. Submitters are allowed to attach files, while approvers may only view the attached files.


To do this, I first put together an ASP.NET 2.0 webform (Upload.aspx) with FileUpload controls in a DetailsView bound to a SqlDataSource. That was the easy part. Upload.aspx is styled to look like the rest of the webapp. (Read this article for a tutorial on how to do this.)

To connect this new upload functionality to our existing application, I load a JavaScript file into all target webforms. This client-side script, customization.js, creates an iframe containing Upload.aspx, and attaches custom events to the existing form submit buttons.

Creating the Iframe
The iframe creator method, in customization.js, using DOM and innerHTML:


// buildContainer() is called on load
function buildContainer(target, id, mode) {
var container = document.createElement("div");

container.innerHTML = [
'<iframe name="uploader" id="uploader" ',
'frameborder="0" scrolling="no" ',
'src="Upload.aspx?',id=',id||'','&mode=',mode||'','"',
'></iframe>'
].join('');

target.appendChild(container);
}

Notice that id and mode parameters are passed through the query string.

If an id parameter is passed, Upload.aspx will assume the document has previously been created. It will set the DetailsView.DefaultMode to Edit, query the database for attachments and binds the UI appropriately. Otherwise, the DetailsView will stay in the default Insert mode.

The mode parameter is used in conjunction with an existing document id to indicate whether the FileUpload controls rendered should allow user editing of the attachments.

After dynamically inserting an iframe into the webform DOM, I added custom events to trigger Upload.aspx to uploaded and link the attachments to the current document.

Adding client-side events to trigger file uploads
On each submitter form, there may be one or more buttons which saves the document e.g. "Save as Draft" and "Save and Submit". We want each of these buttons to also cause the iframed Upload.aspx to upload the attachments.

Here's the code, also in customization.js:


(function(button_ids){

/* FileUploaded is called from Upload.aspx
* after it successfully saves the attachments.
*/
window.FileUploaded = function(goto_id, doc_key) {
document.getElementById('Notes').value+='|'+doc_key;
document.getElementById(goto_id).click();
}


for(var i in button_ids) {
var button_id = button_ids[i];
var button = document.getElementById(button_id);

if(button) {
var newbutton = document.createElement('button');

// copy all existing button attributes
newbutton.innerText = button.value;
newbutton.className = button.className;
newbutton.disabled = button.disabled;

newbutton.executed = false;
newbutton.goto_id = button_id;
newbutton.id = 'proxy_' + button_id;

// newbutton tells Upload.aspx to save
newbutton.onclick =
function() {
if(!this.executed) {
frames.uploader.Save(this.goto_id, newid());
}
return false;
}


// newbutton added, and old button is hidden
button.parentNode.insertBefore(newbutton, button);
button.style.display = 'none';

} // end if(button)
} // end for all buttons

})(['Button1','Button2']);

Briefly, an anonymous function is run on page load, called with an array of button ids. After I cloned these buttons - cloneNode() did not work properly for me, so I created the buttons from scratch - I hid them from the user and added the clones to the UI.

I attached events to the clones' onclick handlers, which would, when clicked, call the client-side Save() method in Upload.aspx. The Save() method:


function Save(goto_id, document_key) {
document.getElementById('GotoIdTextBox').value = goto_id;
document.getElementById('DocKeyTextBox').value = document_key;
document.getElementById('SubmitButton').click();
}

The goto_id passed is the id of the "real" button, which is the origin of clone. The document_key is a random script generated key to couple the document and its uploads.

Tying the document with its attachments
After Upload.aspx saves the attachments, it will call the containing frame's FileUploaded() method, with the id of the triggering clone button's source button. In Upload.aspx's script block:


/* UploadDataSource_Updated() outputs
* the same client-side script
*/
private void UploadDataSource_Inserted(
Object sender,
SqlDataSourceStatusEventArgs e)
{
this.Controls.Add(
new LiteralControl(
"<script>" +
"parent.FileUploaded(" +
"'"+GotoIdTextBox.Text+"'," +
"'"+DocKeyTextBox.Text+"');" +
"</script>")
);
}


The line document.getElementById('Notes').value+='|'+doc_key; in FileUploaded() hijacks the Notes field and appends the script-generated key. Thus, the creation of an artificial data link.


When in edit or viewing mode, the id will be extracted from the Notes TextBox on page load and truncated. So, the user does not see this random string at all.

Conclusion
Looks and feels wrong, doesn't it? Well, we're rolling this out to our customers soon. If only the webapp had inline-scripted webforms, I wouldn't have gone this way.

Again, and I know you guys don't like to comment, but how would you have done things differently?

Monday, October 15, 2007

Scott Guthrie blogs about the ASP.NET MVC Framework

Finally, a blog post from Scott about the ASP.NET MVC Framework. It's mostly what the recent ALT.NET Conference attendees have been reporting; Roll your own (apparently) - the conference, not the framework - if you missed out on the conference, just don't expect another awesome ScottGu unveiling to happen. Great to know we'll be able to get our hands on the framework soon.

We'll be releasing a public preview of this ASP.NET MVC Framework a little later this year. We'll then ship it as a fully supported ASP.NET feature in the first half of next year.

Fuyoh.

Friday, October 12, 2007

Bad way to extend an ASP.NET product

How do you extend your ASP.NET product when you have no access to the source code?

First, some background: We received a customization order to add webmail-style attachments to our webapp, the kind of easy job we let our junior developers cut to their teeth on. However, the target app was developed by an ex-partner, one who've parted ways with bridges burning and much bad blood. Cutting the drama short, we didn't have the code. We could make changes to the ASPX file and the DB sprocs, but we couldn't add new code-behind and class level business logic into the app.

Of course, we could've reverse-engineered the web project and recompiled the whole thing anew with our extended functionalities. But, we went a different way. The bad way.


We used JavaScript to hack the customized features into our app. The script dynamically adds an iframe (containing the upload attachments functionality) to each target webpage. When the existing webpage's form submit event is triggered, the iframe page hijacks the client-side event handler and posts back, uploading the attachments. Each attachment is saved into a binary column on a newly created database table, and artificial keys are created on both the primary and this new table to provide referential coupling.

I'll go into the technical details in upcoming posts. What I'd like to do is discuss the rationale of our approach:

1. We minimized and isolated modifications to an unsupported piece of software.
With our ex-partners withholding support and source code, we tried not to introduce changes into software we didn't develop and can't test. The best way is to use Reflector or some other tool to reverse engineer the software and recompile it. But, a tight delivery deadline meant we didn't have the time to learn to do this (it might've taken only an afternoon for all we know), so we decided to use client-side scripting. And because we didn't hack the ASP.NET 1.1 webproject,

2. We didn't have to migrate the software to use ASP.NET 2.0's RAD controls
When the order came in, I immediately thought to use 2.0's FileUpload , DetailsView, and SqlDataSource controls. These provided a very fast way to create all the attachments functionality in one single ASPX file, with very little code. UI data-binding and database access were a breeze. Eveything worked almost right out of the box, I'd only needed custom (inline) codes for DetailsView.ItemInserting and DetailsView.ItemUpdating, plus some CSS to make the new page fit in with the look and feel of the target app.

3. Installation of the new features is a no-brainer
No need to redeploy the whole project, which would mean some system downtime. Installation would be, create a new virtual directory within the same domain (but running ASP.NET 2.0), create the new attachments DB table, and copy the attachments ASPX and JS file. We needed only one line of JavaScript added into a existing common JS file, to call our extended features script. So, this is the single one point of change in the existing software.

But, I can't help but feel that what we're doing isn't right. It's the same feeling I got when we added random client-side scripts into our other software, the same feeling that tells me this will be coming back to haunt me.

How would you have done things differently?

Wednesday, October 10, 2007

Bad way to add client-side events in ASP.NET

Before the coming of AJAX.NET (and its Control Toolkit), we built our enterprise[y]-grade ASP.NET applications with C# and a lot of hand-coded JavaScripts. One of the JavaScript snippets becoming increasingly tedious to maintain:


(function() {
var originalOnclick =
Button1.onclick || function(){ Button1.click() };

Button1.onclick = function() {
doMore();
originalOnclick();
}
})();

This pattern, enclosed in a script block, usually at the end of the webpage, or called upon page load, adds additional functionality, doMore(), to Button1.

The originalOnclick() method captures existing client-side onclick events handlers. This could be the form submit, which is usually the case, or some ASP.NET-rendered validation subroutine. So, when Button1 is clicked, the newly assigned event handler fires, running first doMore() and then originalOnclick(). Typically, we'd use this to employ browser confirm dialogs to a 'edit' or 'delete' button.

Sounds fairly harmless (even recommended others to use this), until you have to maintain about a hundred varieties of it.

I wish we'd taken the time and trouble to change everything to the Button.onClientClick property when we moved to ASP.NET 2.0. Either that, or use proper JavaScript addEvents/attachEvent. Or better yet, move completely to a testable framework.

Tuesday, October 9, 2007

ASP.NET gets agile

Yesterday, from the rumblings on the ground, I posted a link about the upcoming ASP.NET MVC framework. All the positive noise is making me wish I were at last weekend's ALT.NET Conference in Texas. There's a Yahoo! Group set up, so those of us from far away can still participate.

Whether this is Alternative .NET or just Practical .NET, it's a conversation and that's a a good thing.

Scott Hanselman, understatedly, considering. He put up about a combined 90 minutes of Silverlight screencasts of Scott Guthrie's MVC presentation, and also of the one he did himself with the new framework using DLR languages. Conversation is indeed a good thing! Ruby guy Mike Moore, had this to say about the new framework:

I was really surprised to see how well thought out the framework is, and how extensible and testable the code you can write in it can be. Throughout the demo [ScottGu] highlighted features that were inspired by web frameworks that real developers are using like MonoRail or Rails or Django. He also showed how it was designed to be testable using any of the current unit testing frameworks. Even more surprising that is uses the current ASP.NET stack, Provider model, Request and Response objects, *.aspx/*.master files, etc. The framework seemed to me to be a brilliant combination of idiomatic .NET features and the agile development practices espoused by open source web frameworks.

Can hardly wait.

Monday, October 8, 2007

Microsoft's MVC Framework for ASP.NET

Scott Guthrie announced last weekend at the ALT.NET Conference that an ASP.NET Model-View-Controller (MVC) framework is in the works. Some of the planned features reported:


# Natively support TDD model for controllers.
# Provide ASPX (without viewstate or postbacks) as a view engine
# Provide a hook for other view engines from MonoRail, etc.
# Support IoC containers for controller creation and DI on the controllers
# Provide complete control over URLs and navigation
# Be pluggable throughout
# Separation of concerns
# Integrate nicely within ASP.NET
# Support static as well as dynamic languages

It's MVC for .NET web development, like MonoRail, but without ActiveRecords. Exciting to see Microsoft mainstreaming this Agile framework, but I wonder where it'll sit with the Model-View-Presenter of Patterns and Practices's Web Client Software Factory.

Friday, October 5, 2007

Integrating the jQuery datepicker control into ASP.NET

UPDATE: My apologies, the title is misleading, this post isn't so much about ASP.NET integration as it is about integrating the jQuery datepicker into webpages with existing JavaScript. You can also read about using jQuery with other libraries in the official documentation. But, check it out, Rick Strahl blogged Monday about wrapping the jQuery calendar into a postback-aware ASP.NET control.

My original post:


One of the smallest ASP.NET software products that I maintain here at work uses a custom UI layer, which doesn't conform to any of the .NET architecture best practices and patterns. It uses a custom built template engine, that relies heavily on JavaScript, to render its contents.

When the software was written, Microsoft's AJAX.NET and its Control Toolkit weren't yet around to buoy me from hand-coding what I'd thought were better and faster UI solutions to the default ASP.NET way of doing things.

Comes back to haunt me, this mistake.

Recently, I'd needed to fix a buggy JavaScript datepicker control. Since our non-conformant code kept me from leveraging freely available ASP.NET datepicker controls, I decided to replace the thing altogether. I bit the bullet and went with jQuery's calendar control. My experience doing this follows.

After reading some examples, I jumped right in. Fortunately, I had sufficient foresight to have originally implemented the datepicker using unobtrusive JavaScripts. This meant, all I needed to do was change my one external JS file. After referencing jQuery and the jQuery calendar library scripts, I removed the old initializing code, and put this snippet in:


<script>
jQuery.noConflict();
jQuery(document).ready(function($){
$('.OurDateClass').calendar();
});
</script>

This worked, but only after I dealt with some problems that arose:
1. The calendar script didn't work with noConflict.
2. The web application already implemented an Array.Prototype.concat.

So, I modified the jQuery Calendar JS file to work with noConflict. Firstly, I replaced all $ with jQuery in the PopUpCal and PopUpCalInstance class definitions. Secondly, I encapsulated the rest of the code into an anonymous function which takes in jQuery as $, like so:


(function($){
...
// all the jQuery Calendar inline executing code
...
})(jQuery);

I also had to make sure all HTML element events that were created in JavaScript text were changed accordingly, ie.


html += ' onmouseout="jQuery(this).addClass(...)"';
/* previously
html += ' onmouseout="$(this).addClass(...)"';
*/

Then, after dealing with the Calendar plugin's noConflict, I moved on to the next problem. I decided to just change my existing Array.Prototype.concat extension into Array.Prototype.concatenate. I had to change all the existing calling code as well. Everything worked fine after that, but I can't help wondering if there's some way to namespace JavaScript prototype extensions so there'd be no conflicts.

Anyway, an email from Marc Grabanski, author of jQuery's Calendar plugin, assured me that many of the issues will be addressed in the next version (2.8) release of the plugin.

With careful consideration, upgrading the jQuery core and Calendar plugin in your ASP.NET web application should be relatively painless, requiring only replacing JS files with newer versions.

Read also at this link about how you can use jQuery's AJAX in your ASP.NET application.

Thursday, October 4, 2007

Hosting for your dotnet Facebook application

My Facebook application is currently only one HTML webpage file. As such, my hosting requirements are pretty low, no need of ASP.NET capabilities. Any vanilla-HTML serving webserver will do.

But, a recent project with requirements for hosted ASP.NET have set me looking for a free and decent webserver. A Google search for "free ASP.NET hosting" yielded these results:

Quantasoft Web Hosting
WebHostForASP.NET
ChristianASP.NET
AspSpider.NET
AspHost4Free

You can use these to host your .NET Facebook applications as well, just watch out for the bandwidth limits if you expect your app to be hugely popular.

My previous posts on programming for the Facebook platform:
FBML tags in my Facebook application
Lessons in FBJS
How I created a Facebook application with FBJS

Wednesday, September 19, 2007

Stuff from October 2007 MSDN Mag

Most of the October '07 MSDN Magazine is about concurrent programming. There are, however, two articles directly related to programming for the internet. The first article focused on AJAX.NET application architecture. The author talked about how login differs from standard ASP.NET, REST and JSON (as well as SOAP services), security concerns, and partial rendering to build a dynamic UI. The second article showed how Virtual Earth was pulled into Excel to enhance a wedding guest list. Check it out.