dGallery, a sexy asp.net mvc photo gallery

Posted in ASP.NET | MVC at Tuesday, September 16, 2014 10:49 AM GMT Daylight Time

dGallery, asp.net mvc5 photo gallery

check the demo

  • No database required
  • Quick, smart, keyboard based navigation
  • Sign in with your Twitter and Facebook account
  • Super-simple, super-fast
  • Full source code is included. Easy to extend and customize it to fit your needs.
  • EXIF reader.
  • It uses bootstrap. Just go to bootswatch and download a new theme or create your own. It is a simple drag and drop.

AddThis Social Bookmark Button

Invoicing application in ASP.NET MVC3 - full source code

Posted in .NET 4 | ASP.NET MVC3 | Visual Studio 2010 at Tuesday, October 11, 2011 2:28 PM GMT Daylight Time

About this example application

I have recently created an example invoicing application in ASP.NET MVC3 in order to have a starting code base for my daily work as ASP.NET MVC3 trainer and developer.

You can make the most of this application by following the development history log and learning about every aspect of ASP.MVC3 covered here (authentication, partial rendering, code first, EF, templates, scaffolding, ajax partial rendering, t4 templates, etc)

As companies and students I trained did, hope you guys that are stepping now into ASP.NET MVC find it useful.

Feel free to fork this application in github, send feedback, or contribute to the code base by sending a pull request.

This project was started a few days ago (30th Sept 2011), so more features will be adding soon.


Full source code, screenshots and online demo


What does this example ASP.NET MVC3 application cover?

  • Data modeling using Code First and POCO entities.
  • Use of SQL Server Compact (SQL CE) (actually you can select whatever database backend you want (SQL Server, SQL Server Express, SQL CE, etc) by editing the web.config file).
  • LINQ and Entity Framework.
  • Razor view engine.
  • Partial views and partial actions. Partial actions caching.
  • Html Helpers
  • EditorTemplates and DisplayTemplates for custom rendering common types across the application (decimal, datetime)
  • Creating a custom authentication provider pointing to your database "users" table (Custom Membership Provider) exact code file here
  • Data Annotations validations.
  • AJAX Partial view rendering using jQuery.
  • Custom T4 templates for customized scaffolding. The templates have been adapted to (Twitter Bootstrap CSS).
  • Unit testing using NUnit. Object mocking using Moq.
  • Otros: Twitter Bootstrap CSS, Google Charts.

How to follow the release history to see what has been added in each release?

How to follow the tag history

Development has been done step by step.

Every release has been marked with a TAG, so you can explore the source code from the first line of code created, seeing what has been added to each release (by checking the history file) and comparing it with the source code related to that TAG, available in GitHub.

This way you would be able to follow the whole development process.

Better check the github page for this project


AddThis Social Bookmark Button

Error handling in ASP.NET MVC3

Posted in ASP.NET MVC3 | MVC at Tuesday, April 12, 2011 9:38 AM GMT Daylight Time

[HandleError]

In ASP.NET MVC (versions 1 to 3) we have the [HandleError] attribute, that will allow us to handle errors in a very easy way.

Just by decorating an action (or controller if we want to extend HandleError behaviour to all actions on that controller) with the HandleError attribute and enabling “CustomErrors” in web.config, we get a nice redirection to a friendly view in case an unhandled error raises.

Internally, we could have a look at the implementation of OnException method inside HandleError using Reflector to see how it works:

As we can see, the unhandled exception will be handled if it hasn't been already marked as "handled" and if custom error handling is enabled .

Web.config customErrors section

The CustomErrors section allow us to define automatic error handling behaviour. If it doesn't exists, it must be created inside system.web section. as shown here:

Posible values for mode are "Off | On | RemoteOnly". This will allow us to easy define behaviour for development and production scenarios :

  • On: custom error handling enabled
  • Off: custom error handling disabled. If an error is raised, we will see the yellow screen of death of ASP.NET
  • RemoteOnly: if we launch the application in the local server (targeting http://localhost ), we won't see custom errors. If we access the application from other machine, we will see custom erros. This option is used by developers to debug applications. If there is an error, you can always (among other things) RD to your server and launch the application in a local browser so you see the exception in a first seat.

Behaviour

  • If we use the HandleError attribute and CustomErrors is enabled,w hen an unhandled error raises, the MVC runtimewill look for a “Errors.aspx” view in the context of the HttpRequest being processed (current view folder associated to controller or shared view folder), and will render it. In this case the "defaultredirect" and "redirect" CustomErrors attributes are ignored
  • If we don't use the HandleError attribute and CustomErrors is enabled , we will get an HTTP redirection to the url defined on the "redirect" and "defaultredirect" attributes, within the CustomErrors section in web.config (in our case, /Error/General)

Important: ASP.NET MVC3, registers the HandleError attribute globally (for all controllers) !! (see image). Take that into account so you don't think your MVC3 controlleris not using the HandleError attribute (by default it is). In previous versions of  ASP.NET MVC, where we didn't have global filters, the HandleError attribute had to be defined manually for each action or controller.

Also important: If you have enabled CustomErrors=On , also added the [HandleError ] and still get a yellow screen of death please make sure the Error.aspx has no errors (check master page and the errors.aspx code) , it may have an error (this is pretty common scenario and difficult to debug).You can check if this is happening simple by temporaly removing all Error.aspx code and replacing by a text (más información)

To avoid showing ASP.NET yellow screen of death if your Error.aspx has errors, use "redirect" CustomErrros attribute to show a static  html page.

Controller OnException

Alternatively to HandleError, we can also override the OnException  method of a controller (or all of them if we use a base controller class).

An example of exception handling, logging and redirection to friendly message would be:

Noe: the OnException event is executed independly of the use of HandleError in the controler.

Using Elmah to intercept, log and notify of unhandled errors

Elmah is a fantastic library that help us to intercept, register (in the desired format: database, text file, xml, etc) and optionally deliverunhandled errors ocurred in our application, so we keep everything in control at all times. It also provieds a web interface so you can access the error records remotely, and a RSS feed so you can subscribe with your favorite RSS reader.

With NuGet , a library package manager, available with ASP.NET MVC3, install Elmah is a pretty straightforward process. First step is launching NuGet:

Then, we search for "Elmah":

and proceed to install it. NuGet will handle for us the necessary steps required to install and configure it (in previous versions of ASP.NET MVC we had to do it manuall). NuGet does for us:

  • downloads the last version from the oficial repository
  • adds the assembly reference to our project
  • modifies the web.config to add the proper configuration parameters

In our case, Elmah needs some parameters and configuration sections (httpModules,httpHandlers, etc)  in order to work del web.config :

If we want Elmah to record errors or events in XML files inside a certain directory , we have to indicate it::

And that's it.. When an unhandled error is raised, Elmah will be able to intercept it and record it, and also send an email to the administrator. 

Registering with Elmah custom events and errors

Elmah offers an API so we can record or own events or exceptions . We can use that funcionality to log exceptions that we have already handled with our code. Example:

Elmah and HandleError

Elmah works perfectly with unhandled exceptions (yellow screen of death), but won't be able to intercept exceptions that are being handled by the [HandleError] attribute.

To fix this, we need to create a custom HandleError attribute and add a custom behaviour to the new attribute.

More details and source code here: http://stackoverflow.com/questions/766610/how-to-get-elmah-to-work-with-asp-net-mvc-handleerror-attribute

 

Filtering unwanted events in Elmah

If Elmah is logging too many stuff, (ex: 404 errors looking for favicon.ico), I have the posibility of applying custom filters to those unwanted events .

First, we must add the Elmah ErrorFilter module to web.config:

Once registered, we implement the following events on Global.asax.cs, defining the filtering rules I want to apply:

Final notes

In my particular experience, I found the best practice to use the custom HandleError as shown in the last part of this article (having the HandleError applied globaly) with CustomErrors enabled, helped by Elmah to handle, register and send unhandled exceptions . When necessary, I use the Elmah signal capabilities for those handled exceptions I want to log.

I also use a lot the Elmah error viewer with some filters applied (to hide most of 404 errors, for instance) and the RSS feed, added too my Google Gmail webclips :-)


Referencias

AddThis Social Bookmark Button

Secure, synchronized, multiplatform password management

Posted in DropBox | Productivity at Wednesday, March 31, 2010 10:22 AM GMT Daylight Time

Nota: Artículo disponible en castellano aquí / spanish version available here

If you use more than one computer (maybe with different SO) and manage lots of complex passwords (you should), you will need:

  • To store the passwords in a secure way.
  • To able to access them from any machine or platform and keep them synchronized.
  • Ideally, you would like to enter the password in whatever site or service in a quick and secure way auto-type functionallity(see below for auto-type functionality, it is cool)
  • Be able to define expiration dates for password renewaland get reminders from your password manager to do so

Conclusion: After some research I decide to use this combination of tools:: KeePass + DropBox

Main picture

DropBox and KeePass
  1. Install KeePass or KeePassX in every machine. Multiplatform
  2. Install DropBox in every machine. Also multiplatform
  3. The password file stays always encrypted and synchronizedthrough DropBox
  4. The password file stays double protected: on one way, you have a very secure encryption algorithm on KeePass. You also have an extra layer of encryption with DropBox .
  5. If the password file gets corrupted, DropBox let you go to the previous version of the file (DropBox keeps a history of file changes)

Installation

You can download KeePass here (for Windows) , use dpkg for Linux to get KeePassX, or download it from:  http://www.keepassx.org/ From KeePassX web site:
"Originally KeePassX was called KeePass/L for Linux since it was a port of Windows password manager Keepass Password Safe. After KeePass/L became a cross platform application the name was not appropriate anymore and therefore, on 22 March 2006 it has been changed."

The idea is installing KeePass and store the KDB file (the password file) in your DropBox.

The password file is synchronized across your machines, and can be opened by KeePass on Windows, or KeePassX in Linux or MacOs.

Security

The password file is protected by usign a encryption algorithm considered safe (see http://keepass.info/help/base/security.html for more detaiils). The sensible data remains encrypted in memory while in use.

"In order to generate the 256-bit key for the block ciphers, the Secure Hash Algorithm SHA-256 is used. This algorithm compresses the user key provided by the user (consisting of password and/or key file) to a fixed-size key of 256 bits. This transformation is one-way, i.e. it is computationally infeasible to invert the hash function or find a second message that compresses to the same hash. The recently discovered attack against SHA-1 [2] doesn't affect the security of SHA-256. SHA-256 is still considered as being very secure [3]."

Auto-type functionality

Using auto-type functionality you can sign-in using your credentials in a fast and secure way. Watch the video:

Any comment or sugestion?

AddThis Social Bookmark Button

Working with SVN and DropBox without a dedicated SVN server

Posted in Productivity | SVN | DropBox at Wednesday, March 24, 2010 4:41 PM GMT Standard Time

What is DropBox?

DropBox is a service that keeps a certain folder in your computer sincronized with other computers (your laptop, desktop, dev server, your team`s dev machines, etc). Whatever file you put or change on your DropBox folder, it will be changed and syncronized across all your computers, whatever they are running Windows, Linux or Macintosh.

From DropBox.com web site:

  • 2GB of online storage for free, with up to 100GB available to paying customers.
  • Sync files of any size or type.
  • Sync Windows, Mac and Linux computers.
  • Automatically syncs when new files or changes are detected.
  • Work on files in your Dropbox even if you're offline. Your changes sync once your computer has an Internet connection again.
  • Dropbox transfers will correctly resume where they left off if the connection drops.
  • Efficient sync - only the pieces of a file that changed (not the whole file) are synced. This saves you time.
  • Doesn't hog your Internet connection. You can manually set bandwidth limits.

[read more about DropBox features on their web site...]

Ok, we are software developers, what about using DropBox as a code repository?

Some folks use DropBox as a code repository. DropBox allows file versioning and maintains the history of every change made on your code (see screenshot):

Using DropBox as source code repository
[Image: Using DropBox as code repository]

Yeah, but I prefer SVN for managing code (merging, tagging, branching...)

This DropBox thing is ok, but you sure prefer all the power behind SVN: merging, branching, tagging, etc... and of course, you may feel better knowing that SVN is open source (what if suddenly DropBox closes business and you lose all the history of your source code??).

In the other hand, you are a freelancer or a small team of developers and DON'T need or want to maintain a dedicated SVN server 24x7 on the internet.

The solution is pretty simple, keep reading:

How to work with SVN and DropBox checking code across computers with a global repository URL?

  1. Install DropBox in every machine you use for development. DropBox is multi-platform (Windows, Linux and Mac so far). If you use this link, we both get an extra 250Mb of free space.
  2. Install the proper SVN Server for your O.S, pointing the SVN repository to the DropBox folder, so it will be sincronized across all computers.
    Visual SVN Server for Windows

    Using DropBox as source code repository
  3. If you want to use a global SVN URL across machines (ex: http://svn.mycoolcompany.com/svn/myproject), you need to modify hosts file so it points to localhost. The hosts file is used by your computer in the first attempt to resolver a name into an IP adress. You need to edit it, and add a line like this (make sure you open the file with the right permissions)
    127.0.0.1   svn.midominio.com  #whatever domain or subdomain you choose will work.
    
    Editing HOSTS file

    Cheching out from SVN using the global URL
    If you add the above line to HOSTS file in every computer, you could checkout a project like https://svn.iloire.com/svn/myproject, no matter in which computer you are at, since every computer will resolve that to localhost, and will connect to the local repository sincronized with DropBox.

And you got it, you have just created a SVN environment that will be online 24x7 without a dedicated SVN server using DropBox!

AddThis Social Bookmark Button

.NET Serialization (using BinaryFormater, SoapFormatter and XmlSerializer)

Posted in Performance | Serialization at Sunday, March 22, 2009 1:06 PM GMT Standard Time

Object serialization is the process of converting an object to a format that is suitable for persistence (database, file, etc) or transportation (remoting, Web Services, MSMQ, etc).

The format of the output byte stream is governed by a formatter object. When you serialize data, you construct a formatter object that implements the required format.

With .NET Framework 2.0 and above you can use two formatters: BinaryFormatter and SoapFormatter. You can also serialize objects (well, just the public members, not the private ones - which is know as shallow serialization) by using the XMLSerializer class.

The following class Person implements some attributes that are used in the process of seralization. This class is also used on the application example you can download below.

 [Serializable] //<-- This atribute is just required by BinaryFormatter and SoapFormatter
    public class Person  //<-- XMLSerializer needs that the class is defined as public
    {
        //[System.Xml.Serialization.XmlIgnore]   //<-- using this attribute, this field will be ignored in Xml Serialization        

        public string FirstName; //Some few public properties to serialize. They  will be serialize by the three formatters.

        public string LastName;                
               
        [NonSerialized] //<-- Using this attribute, the field Nationality won't be serialized (by any of the three serializers)
        public string Nationality;        
        
        private string _Address; //this private field won't be serialized using XmlSerialization. They will be serialized using Binary or Soap formatters

        private string _ZIPCode; //this private field won't be serialized  using XmlSerialization. They will be serialized using Binary or Soap formatters

		//let's create a method to set the private properties.
        public void SetAddress(string address, string zipCode) 
        {
            _Address = address;
            _ZIPCode = zipCode;
        }

        public override string ToString()
        {
            return string.Format("I'm {0} {1} from {2}!. Address: {3}, {4}", 
				FirstName,LastName,Nationality, _Address,_ZIPCode);
        }
    }

Serialization formatters in the .NET Framework

1) BinaryFormatter (System.Runtime.Serialization.Formatters.Binary namespace)

  • Serializes and object in an internal binary format that the .NET Framework understands.
  • The type needs to be marked with the [Serializable] atribute (see class Person)
  • BinaryFormatter saves metadata (assembly and type information) on the output stream along with object data. This information is necessary to deserialize the data and rebuild the object in memory.

PROS

  • The output byte stream generated is compact
  • The serialization process is faster than using the other formatters.
  • This formatter can serialize generic and non generic collections (being the items within the collection serializable)
  • Serializes public and private members (deep serialization)

CONS

  • Format not readable by other techonolgies (just .NET Framework)

BinaryFormatter serialization use example

Person p=new Person();
string path=@"c:\myfile.bin";
using (System.IO.FileStream fs = new System.IO.FileStream(path, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write))
{
	System.Runtime.Serialization.Formatters.Binary.BinaryFormatter b = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
	b.Serialize(fs, p);
	fs.Close();
}

This code will serialize object p (type Person) on file c:\myfile.bin with binary format

BinaryFormatter deserialization use example:

string path=@"c:\myfile.bin";
using (System.IO.FileStream ds = new System.IO.FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
	System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
	Person p = bf.Deserialize(ds) as Person;	
}

This code will deserialize object p (type Person) from c:\myfile.bin

2) SoapFormatter (System.Runtime.Serialization.Formatters.Soap namespace)

  • Serializes an object in SOAP format.
  • The type also needs to be marked with the [Serializable] atribute.
  • To use this class you need a reference to the System.Runtime.Serialization.Soap assembly.
  • This formatter also saves metadata (assembly and type information) on the output stream along with object data.

PROS

  • Follows a standard (SOAP) that other platforms can understand.
  • Serializes public and private members (deep serialization)

CONS

  • It is more verbose (less efficient) than BinaryFormatter.
  • It can NOT serialize generic collections (System.Collections.Generic namespace)

SoapFormatter serialization use example:

Person p=new Person();
string path=@"c:\myfile.soap";
using (System.IO.FileStream fs = new System.IO.FileStream(path, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write))
{
	System.Runtime.Serialization.Formatters.Soap.SoapFormatter
	f = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();
	f.Serialize(fs, p);
	fs.Close();
}

This code will serialize object p (type Person) on file c:\myfile.soap with Soap format

SoapFormatter deserialization use example:

string path=@"c:\myfile.soap";
using (System.IO.FileStream ds = new System.IO.FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
	System.Runtime.Serialization.Formatters.Soap.SoapFormatter sf = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();
	Person p = sf.Deserialize(ds) as Person;
	AppendToLog(string.Format("Single person deserialized from {0} in SOAP format: {1}", path, p));
}

This code will deserialize object p (type Person) from file on c:\myfile.soap using Soap formatter

A Person object after Soap serialization looks like this:

<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
	<SOAP-ENV:Body>
		<a1:Person id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/Serialization/dotneat_net.Serialization%2C%20Version%3D0.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull">
			<FirstName id="ref-3">Joe</FirstName>
			<LastName id="ref-4">Doe</LastName>
			<_Address id="ref-5">dotneat.net Street, Zaragoza, Spain</_Address>
			<_ZIPCode id="ref-6">50007</_ZIPCode>
		</a1:Person>
	</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

3) XMLSerializer

  • Serializes and object in XML format.
  • Requeriments:
    • Type must be public (public class person)
    • Must implement a parameterless constructor (in order to deserialize the object)
    • If you are serializing a non generic collection of items, you must pass the types that are stored in the collection as a parameter in the constructor of the XmlSerializer (see example code).

PROS

  • It can serialize generic and non generic collections (being the items within the collection serializable)
  • Class doesn't need to be decorated with [Serializable] attribute.
  • Developer has a deep control about how each field is going to be serialized by using the attributes:
    • [XmlAttribute] : over a field, marks that the field will be serialized as attribute, instead of a node
    • [XmlIgnore] : won't serialize that field. The same as NonSerializable, but just for the XmlSerializer.
    • [XmlElement (ElementName="NewName"]: Allows you to rename the field when being serialized.
    • ....

CONS

  • Only public members will be serialize! (shallow serialization) (both BinaryFormatter and SoapFormatter would serialize also object private members)

XmlSerializer serialization use example:

Person p=new Person();
string path=@"c:\myfile.xml";
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(Person));
using (System.IO.FileStream xmlStream = new System.IO.FileStream(path, System.IO.FileMode.Create, System.IO.FileAccess.Write))
{
	serializer.Serialize(xmlStream, p);
	xmlStream.Close();
}

This code will serialize object p (type Person) on file on c:\myfile.xml using the XmlSerializer class

XmlSerializer deserialization use example:

string path=@"c:\myfile.xml";
System.Xml.Serialization.XmlSerializer dxml = new System.Xml.Serialization.XmlSerializer(typeof(Person));
using (System.IO.FileStream xmlStream = new System.IO.FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
	Person p = dxml.Deserialize(xmlStream) as Person;
	xmlStream.Close();
}                

This code will deserialize object p (type Person) from file c:\myfile.xml using the XmlSerializer class

A Person object after XML serialization looks like this (see how just public members are serialized):

<?xml version="1.0"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <FirstName>Joe</FirstName>
  <LastName>Doe</LastName>
</Person>

As you may see, private members are not serialized.

Selecting Fields to serialize

You can omit fields from being serialized by marking them with the [NonSerialized] attribute (see Nationality field in Person class).

Customizing the process of serialization and deserialization

If you are required to, you can modify the way the data in objects is serialized and deserialized. For example, you may want to serialize the account number and pass code of the class BackAccount crypted (just those two fields)

Serialization process

You need to implement the interface ISerializable on the class to serialize. If the type implements ISerializable interface, the formatter calls the GetObjectData to convert the object into the stream of bytes.

Use OnSerializingAttribute and OnSerializedAttribute to mark methods that will be executed before and after the serialization takes place.

[Serializable]
public class Person : ISerializable{

    .....

    [OnSerializing]
    public void Deserializing (StreamingContext context){
        //before serialization
    }


    [OnSerialized]
    public void Serialized (StreamingContext context){
        //after serialization
    }
}

Deserialization process

It is also possible to control how the deserialization process by implementing a constructor that takes a SerializationInfo and a StreamingContext as parameters.

[Serializable]
public class Person : ISerializable{
    //Deserialization constructor
    private Person(SerializationInfo info, StreamingContext context){
        string fname=info.GetString("FirstName");    
        // ...   
    }
}

Use OnDeserializingAttribute and OnDeserializedAttribute to specify methods to run before and after the object is deserialized.

[Serializable]
public class Person : ISerializable{

    .....

    [OnDeserializing]
    public void Deserializing (StreamingContext context){
        //before deserialization
    }


    [OnDeserialized]
    public void Deserialized (StreamingContext context){
        //after deserialization
    }

}

Example application code


(click on the image to view screenshot in full size)

Serialization application example source code (hosted on google code)

About the example application

You can use the application for serialize/deserialize a simple example class "Person". You can go and check file size and format of output file. You can also serialize/deserilize non generic (ArrayList) and generic (List) collections of Person, so you can see how the formatters serialize those types.

Performance

There is a performance test functionality. You can check which is the faster way of serializing a simple type. Feel free to extend the example to create performance tests that suits your needs

Final review

AddThis Social Bookmark Button

Backgroundworker example

Posted in .NET 2.0 | Performance | Visual Studio 2005 at Tuesday, February 10, 2009 5:57 PM GMT Standard Time

The background worker allows you to execute intense or long operations on a separate thread, without having to deal with threads, invokes or delegates. This is essential in today's cluttered webspace brought forth by the constant growth of broadband technology.

This simple example pretty much cover all posibilities of use of this component: cancellation support, backgroundworker error handling and report progress (also passing UserState data on report progress notifications)

Nota: Este artículo está disponible en castellano aquí

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace BackgroundWorker
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //mandatory. Otherwise will throw an exception when calling ReportProgress method
            backgroundWorker1.WorkerReportsProgress = true; 

            //mandatory. Otherwise we would get an InvalidOperationException when trying to cancel the operation
            backgroundWorker1.WorkerSupportsCancellation = true;
        }



        //This method is executed in a separate thread created by the background worker.
        //so don't try to access any UI controls here!! (unless you use a delegate to do it)
        //this attribute will prevent the debugger to stop here if any exception is raised.
        //[System.Diagnostics.DebuggerNonUserCodeAttribute()]
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            //NOTE: we shouldn't use a try catch block here (unless you rethrow the exception)
            //the backgroundworker will be able to detect any exception on this code.
            //if any exception is produced, it will be available to you on 
            //the RunWorkerCompletedEventArgs object, method backgroundWorker1_RunWorkerCompleted
            //try
            //{
                DateTime start = DateTime.Now;
                e.Result = "";
                for (int i = 0; i < 100; i++)
                {
                    System.Threading.Thread.Sleep(50); //do some intense task here.
                    backgroundWorker1.ReportProgress(i, DateTime.Now); //notify progress to main thread. We also pass time information in UserState to cover this property in the example.
                    //Error handling: uncomment this code if you want to test how an exception is handled by the background worker.
                    //also uncomment the mentioned attribute above to it doesn't stop in the debugger.
                    //if (i == 34)
                    //    throw new Exception("something wrong here!!");

                    //if cancellation is pending, cancel work.
                    if (backgroundWorker1.CancellationPending)
                    {
                        e.Cancel = true; 
                        return;
                    }
                }

                TimeSpan duration = DateTime.Now - start;
                
                //we could return some useful information here, like calculation output, number of items affected, etc.. to the main thread.
                e.Result = "Duration: " + duration.TotalMilliseconds.ToString() + " ms.";
            //}
            //catch(Exception ex){
            //    MessageBox.Show("Don't use try catch here, let the backgroundworker handle it for you!");
            //}
        }


        
        //This event is raised on the main thread.
        //It is safe to access UI controls here.
        private void backgroundWorker1_ProgressChanged(object sender, 
            ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage; //update progress bar
            
            DateTime time = Convert.ToDateTime(e.UserState); //get additional information about progress
            
            //in this example, we log that optional additional info to textbox
            txtOutput.AppendText(time.ToLongTimeString());
            txtOutput.AppendText(Environment.NewLine);            
        }



        //This is executed after the task is complete whatever the task has completed: a) sucessfully, b) with error c)has been cancelled
        private void backgroundWorker1_RunWorkerCompleted(object sender, 
            RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled) {
                MessageBox.Show("The task has been cancelled");
            }
            else if (e.Error != null)
            {                
                MessageBox.Show("Error. Details: " + (e.Error as Exception).ToString());
            }
            else {
                MessageBox.Show("The task has been completed. Results: " + e.Result.ToString());
            }
            
        }




        private void btoCancel_Click(object sender, EventArgs e)
        {
            //notify background worker we want to cancel the operation.
            //this code doesn't actually cancel or kill the thread that is executing the job.
            backgroundWorker1.CancelAsync();
        }

        private void btoStart_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();
        }

      
    }
}

Download sample project

Download BackgroundWorker.ZIP (C# sample project)

AddThis Social Bookmark Button

Avoiding ASPX pages to be updated after delivery (by the client or someone else)

Posted in .NET 2.0 | ASP.NET | Visual Studio 2005 at Tuesday, January 20, 2009 12:05 AM GMT Standard Time

If you go to Build-> Publish Web Site menu on Visual Studio 2005, you will find this publishing screen:

If you UNCHECK the "Allow this precompiled site to be updatable", all the aspx pages within the projects will be generated empty. To be more exact, you will find the following unique line on them:

This is a marker file generated by the precompilation tool, and should not be deleted!

If you compare this screenshot:

with this one:

you will realize how the first was published allowing ASPX pages to be updated and the second not (notice how in second screenshot, all the ASPX files have 1kb file size)

Don't worry!, All HTML markup and inline code is compiled into assemblies on the bin folder, and it is correctly executed and rendered when the page is requested.

This way, nobody would be able to change either code or HTML content after the publishing is done!

AddThis Social Bookmark Button

I am sure you know how to add the predefined TextBox or ComboBox controls to a Windows Forms context Menu:

Just wanted to quickly show you how you can add your own custom controls to that context menu by using the ToolStripControlHost class, like this (the yellow panel is a user control):

Here is a short video:

And here is the code:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //instance my control
            UserControl1 c = new UserControl1();

            //pass as parameter to ToolStripControlHost instance
            ToolStripControlHost host = new ToolStripControlHost(c);

            //add ToolStripControlHost object to context menu. simple!
            contextMenuStrip1.Items.Add(host);
        }
    }
}


 

AddThis Social Bookmark Button

ASP.NET MVC Validation of viewstate MAC failed error

Posted in MVC | ASP.NET | .NET 3.5 at Saturday, December 13, 2008 2:30 AM GMT Standard Time

If you get a Validation of viewstate MAC failed error on ASP.NET MVC, before trying to hard code your <machineKey attribute in web.config, disabling the keying of viewstate

<system.web>
  <pages enableViewStateMac="false" />
</system.web>

, or any other literature you may want to check if the page you are posting data from has two "<form" attributes (the one hard coded on the page and the one created with Html.BeginForm()). If you play with master templates and have to merge some MVC pages with tradicional ASP.NET you may get to that error.

It took me a while to find the solution...

Did this post save you some time? post it. I'm curious. :) thanks.

AddThis Social Bookmark Button

Author

Ivan Loire
Iván Loire (Zaragoza, Spain)

ASP.NET MVC Freelance and Node.js developer

www: home page

View Ivan Loire's profile on LinkedIn
VitaminasDev. Formación software / Software training - Zaragoza
twitter: @ivanloire

On this page...

Recommended books

Tags

Calendar

<October 2014>
SunMonTueWedThuFriSat
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

Archives

Recommended .NET blogs

Syndication

Feed Icon