JitBit Software. Net Profile Switch, Macro Recorder, AspNetForum, RSS Feed Creator.
products download purchase support company blog

Showing posts with label development. Show all posts
Showing posts with label development. Show all posts

Feb 1, 2008

Unknown Icons

Yesterday my friend's 13 years old daughter asked me a question I couldn't answer. "What is that icon on the 'Save' button?" she asked, "What does it mean?"

It took me a couple of moments to figure out what she's talking about. Then it took me several minutes to explain.

"Why would anyone use a 1.5 Mb ugly box, when you can save 4Gb on a tiny flash drive?"

Well, here it is. A whole new generation of users who never saw a 3½-inch diskette.

What should I draw on a save button, so "MySpace-generation" would understand? Is it time to rethink our usability standards? Or should we stick to the classics?

Dec 15, 2007

SEO friendly URLs with ASP.NET

Search engines like human-readable URLs with keywords in it, and hesitate to respect messy URLs with a lot of query-string parameters. So, to make our ASP.NET database-driven website SEO-friendly we have to get rid of our complex URLs.

Example of a "SEO-friendly" URL:
http://www.jitbit.com/mailjet-newsletter-software.aspx

Example of a "SEO-unfriendly" URL:
http://www.jitbit.com/product.aspx?ProductID=18

Solution 1: Fake pages and "Server.Transfer". As you can see the two URLs above point to the same page. Basically it is the same page and it works like this: the page mailjet-newsletter-software.aspx contains no code at all and performs a Server.Transfer (aka server-side redirect) to product.aspx like this:

Server.Transfer("product.aspx?ProductID=18");

That's it. We have one "product.aspx" page which expects a "ProductID" parameter and a lot of "fake pages" with SEO-friendly names like firstproduct.aspx, secondproduct.aspx etc., which simply perform a Server.Transfer to the "product.aspx" with the right ProductID.

Simple, isn't it?

But this solution requires a lot of hard-coding - we will have to create all these fake pages and add a Server.Transfer command. So let's go a little further: we will create one base class for all our "fake pages" and add a record to the "tblProducts" table in the database:

tblProducts
ProductIDProductNameProductPage
1First Productfirstproduct.aspx
2Second Productsecondproduct.aspx
3Third Productthirdproduct.aspx


public class ProductPage : Page
{
private SqlConnection cn;
private SqlCommand cmd;
protected override void OnLoad(EventArgs e)
{
//lets initialize our database connection
//remember to specify the connection string
cn = new SqlConnection(yourConnectionString);
cmd = new SqlCommand();
cmd.Connection = cn;

//determine the page being requested in the browser
string pageFileName = Request.Path.Substring(Request.Path.LastIndexOf("/")+1);

//get the right ProductID from the database
cmd.CommandText = "SELECT ProductID FROM tblProducts WHERE ProductPage=@ProductPage";
cmd.Parameters.AddWithValue("@ProductPage", pageFileName);
cn.Open();
object productID = cmd.ExecuteScalar();
cn.Close();

//if ProductID found
if(productID!=null && productID!=DBNull.Value)
{
//let's transfer the execution
Server.Transfer("product.aspx?ProductID=" + productID.ToString());
}
}
}
Now we have to create our fake pages, inherit them all from the ProductPage class and voi la - that's it! We can also optionally remove all the HTML-code from the aspx-files, leaving the "Page" directive only.

Solution 2: Virtual Pages. This method is pretty similar, except that we don't need to create any pages at all. Instead, we will add an HttpModule, which intercepts HTTP requests, and the user requests a non-existent page, performs a Rewrite operation. First we will create our HttpModule:


namespace URLRewrite
{
public class ProductPageModule : IHttpModule
{
public ProductPageModule()
{
}

public void Dispose()
{
}

public void Init(HttpApplication application)
{
//let's register our event handler
application.PostResolveRequestCache += (new EventHandler(this.Application_OnAfterProcess));
}

private void Application_OnAfterProcess(object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;

//the file being requested is not found
if (!File.Exists(application.Request.PhysicalPath))
{
//replace the "newURL"
//with your own value
string newURL = "product.aspx?ProductID=18";
context.RewritePath(newURL);
}
}
}
}
Now we have to register our HttpModule in the web.config:

<httpModules>
<add type="URLRewrite.ProductPageModule, URLRewrite" name="ProductPageModule" />
<httpModules>

That's it.

Dec 7, 2007

The making of

Just a quick note on what we've been working on for the last two weeks.

After releasing multilingual versions of our forum and helpdesk applications, we received a lot of constructive feedback from our international customers. Mostly, it were feature requests, so the last two weeks were pretty busy.

HelpDesk 2.7.6 (already out) features handy pie-chart diagrams in the "summary" report, customizable email notifications text and many other cool features, including enabled email-notifications in the trial version.

AspNetForum 4.5 (still in development) brings hashed password storage, forum signatures for users, FAQ for users (along with the admin manual) and many other features.

MailJet 2.32 which is also still in development features some minor GUI improvements and a number of performance optimizations.

All these releases are almost finished, and will be out in the next 48 hours.

Dec 5, 2007

Time management tips

Max Kraynov of Kraynov Investments must have read my mind: he shared a great time-management tip, which I use in my daily work too. Here it is: when I open my notebook and start working on a task, I simply turn on the timer on my watch. That's it.

The timer works like a charm: I don't want to pause it and go fill my coffee mug, or pause it and read an email message. The timer makes me more productive and less distracted. And what's more, I'm not afraid of complex tasks any more, since the timer revealed, that even most complicated tasks take 10-15 minutes to complete.

Interesting links:

  • Google has announced the winner of the Adsense Story Contest today: it is http://www.hometips.com/ - a site that features free articles concerning home improvement, remodeling, repair, redecorating, and do-it-yourself projects. For example, tips on how to make your Christmas tree last for weeks.

    The owner, Don Vandervort, says that the AdSense-revenues went from paying for coffee to paying for lunches to paying for all salaries, overhead, and business development.

  • The owner of cdbaby.com tells 7 reasons why he switched back to PHP after 2 years on Rails. He rewrote his website back to PHP after 2-years struggling with Rails. With the help of a Rails "professional" who quit after all.

    Love his last point: "PROGRAMMING LANGUAGES ARE LIKE GIRLFRIENDS: THE NEW ONE IS BETTER BECAUSE YOU ARE BETTER ... the main reason that any programmer learning any new language thinks the new language is SO much better than the old one is because he’s a better programmer now! You look back at your old ugly PHP code, compared to your new beautiful Ruby code, and think, “God that PHP is ugly!” But don’t forget you wrote that PHP years ago and are unfairly discriminating against it now.."

Nov 19, 2007

Jitbit AspNetForum just got better

As you might know, SQL Server Express 2005 has a great feature: it can automatically attach an .MDF file to a running instance of SQL Server Express when an application first establishes a connection. So if you run SQL Server Express - you simply place the database file to some location, modify the database connection string to something like "AttachDbFileName=c:\database.MDF" and you are ready to run.

Another great feature is the ASP.NET "App_Data" folder. If you are familiar with ASP.NET, you know that this special folder holds databases (.mdb and .mdf files), XML files, and other data stored in files. And the user account that is used to run the forum application (for example, the local ASPNET account) already has permissions to read, write, and create files in this folder by default.

Now I can't imagine how stupid we were - we never utilized these two great features before!

So please welcome Asp-Net-Forum 4.4.1.
1) The installation package now comes with a ready-to-use SQL Server Express 2005 database file (MDF-file).
2) Both MS Access sample database and SQL Express sample database files are now located in the "App_Data" folder.

Now, if you want to use the forum under MS Access or SQL Express, forget about dealing with file permissions, and, moreover, forget about editing the connection string! The installation just got easier - simply copy the forum to your website and start working in seconds.

Oct 26, 2007

Uninstall Feedback

All Jitbit programs, when being uninstalled, ask the user, if she/he would like to leave us some feedback. I beleive that every mISV should add uninstall feedback to their product since it's simple and valuable. Even if only 1 user of 10 will leave some feedback, it will give you some food for thought.

But remember to make it optional for your user! Never launch a browser or perform any network activity without asking the user. For example, here is the message shown when someone uninstalls our Macro Recorder:


Still, many users do not read these messages. That's why we receive feedback like this:

"actually, I was just uninstalling to move to my new pc, but ANY site that forces me to visit their site WITHOUT ASKING me, is a site I (and ALL of my Internet friends) will avoid in the future. Your loss!!!!!!!!! Trust me!!"

Makes me sad.

Oct 16, 2007

Net Profile Switch update

Another small note about the recent release of Net Profile Switch - version 5.31.

One of our customers, Paul, who works as a network support engineer, suggested a very good feature. If the tool is used to switch network settings mostly on notebooks, it has to offer a backup/restore (or "import/export") functionality for the profiles. Hard disk failures are very common on laptops, so there has to be a way to backup all the network profiles.

Another point would be that a helpdesk engineer can create a set of network profiles, export it to a file and deploy the file to a number of other computers in the organization, creating the same set of profiles for every user.

The new version also fixes the network drives editor, which had problems removing drives from the list sometimes. Thanks to Andrew, who reported this issue.

Sep 25, 2007

AspNetForum: future plans

Just a short note to let you know we're working on the next version of our ASP.NET forum software which will bring:

  • "closing a thread" feature to make it readonly
  • cleaner source codes and a bit of optmizations
  • users list will show most active forum users, most recent forum users etc.
  • logging "last visit" for all users

And many more. Stay updated.

Sep 8, 2007

ASP.NET: validating custom controls

A short hint for ASP.NET developers... If you want your custom control to be validated by ASP.NET validators, simply add a "ValidationPropertyAttribute" attribute to your class definition. Like this:


[ValidationPropertyAttribute(”Message”)]
public class myCustomControl
{
//"message" property, which we want to be validated
public string Message
{
get { return “My Message”; }
}
}

Aug 9, 2007

Why we still use VB6 for some projects

I've been asked several times, what programming language do we use in our development. Here it is:

Yep, that's right. We still code in Visual Basic 6. We do have modules made with C++, but still we use a lot of VB6. And here is why:
  • VB6 is the only .NET-like rapid development tool, that produces small native Win32 executables (that run fine on Vista, by the way, of course, with some hacks applied)
  • VB6 is so COM-friendly
  • VB6 is widely supported by the community and the Internet is full of articles, manuals, hints and tricks
  • VB6 is rapid, allows to concentrate on the end-user's needs instead of memory management, marshalling and stuff

With VB6 I do miss the "true OOP" features like inheritance, or polymorphism. In fact, ages ago I was a "hardcore" C++ developer, who despised VB6. But now I'm not going back to C++/MFC. Because I'm really spoilt by rapid .NET development. I wish there was a "C# 6", but there isn't, so we stick to VB6. It is almost dead, it will be totally unsupported after 2008, but... it works!

You may ask, why not use .NET to build end-user tools?

  • I believe that our customers need small and fast native executables, that do not require a 25 megs download from Microsoft, and run on older versions of Windows
  • .NET apps are way hard to protect from reverse engineering
  • I don't like the mess with different .NET-framework versions (1.1, 2.0, 3.0 and now even 3.5) that might confuse our customer
  • Basically, .NET is good for developers, .NET is OK for enterprise web-applications, web-services, some complicated distributed database-driven enterprise apps etc. etc., but not for end-user utilities.

I guess when the VB6 is really truly dead, we will think of moving to Delphi, maybe. And again, I wish there was a native compiler for C#... Sigh...

UPDATE: thanks for commenting, mates! We do think of migrating to Delphi. But as far as I know, it has no support for Unicode. Correct me if I'm wrong.