Development With A Dot

Blog on development in general, and specifically on .NET

Sponsors

News

My Friends

My Links

Permanent Posts

Portuguese Communities

March 2009 - Posts

ASP.NET MVC Training Kit Released

Get it here.

Enterprise Library 4.1 and Unity 1.2 Hands-on Labs Download - Patterns & Practices

Good news: the long-promised Hands-on Labs for Unity has been released! 

Get it from here, read about it here.

Changing Thread-Safety Dynamically

Sometimes there may be a need to decide dynamically (through code in your program) whether a class is thread-safe or not. This is the technique I use:

public class SomeClass

{

    private Boolean threadSafe = false;

    private readonly Object syncRoot = new Object();

    //gets or sets whether this object is thread-safe or not

    //in this case we are locking directly on the syncRoot field

    public Boolean ThreadSafe

    {

        get { lock(this.syncRoot) { return(this.threadSafe); } }

        set { lock(this.syncRoot) { this.threadSafe = value; } }

    }

    //Property used for thread synchronization

    public Object SyncRoot

    {

        get

        {

            return(this.ThreadSafe == true ? this.syncRoot : new Object());

        }

    }

    public void SomeMethod()

    {

        //always lock on the SyncRoot property, not the syncRoot field

        lock (this.SyncRoot)

        {

            //do something

        }

    }

}

Posted: Mar 21 2009, 10:34 AM by Ricardo Peres | with 4 comment(s)
Filed under:
ASP.NET MVC 1.0 Released

Get it from http://www.codeplex.com/aspnet, including source code and a sample project.

Interface Inheritance

I am normally against having an interface inherit from another one, but there's a situation where I am in favor of it: web service interfaces!

The reason is that we can write code like this:

using (ChannelFactory<IMyService> factory = new ChannelFactory<IMyService>())

{

    using (IMyService svc = factory.CreateChannel())

    {

    }

}

instead of:

using (ChannelFactory<IMyService> factory = new ChannelFactory<IMyService>())

{

    IMyService svc = factory.CreateChannel();

    using (svc as IDisposable)

    {

        //the generated proxy does implement IDisposable!

    }

}

I think this leads to more elegant code. I know there's a problem with using a ChannelFactory like this, and I will come back to it in a future post! :-)

Enterprise Library 5 Wish List

Updated! 

The guys from the Enterprise Library development team are taking feature suggestions for the upcoming Enterprise Library 5.

I have suggested the following:

  • A configuration editor for Unity, like ther is for all the other application blocks
  • A LINQ provider block
  • Inclusion of XSD schema files for all application blocks, so that we can have intellisense on Visual Studio
  • ADDED: Externalization of the code generation module, like LinFu (I had forgot this one)

You can submit your own here: http://blogs.msdn.com/agile/archive/2009/01/26/enterprise-library-5-what-s-on-your-wish-list.aspx.

Setting Custom Identity in WCF

WCF was designed to be fully extensible, at all levels. If I want to pass a custom identity (an application-defined username and role and the desired culture) to a WCF web service (not using ASP.NET compatibility mode), this is what I do:

  1. I defined a custom AuthenticateAttribute attribute, which implements IContractBehavior, IClientMessageInspector and IDispatchMessageInspector (a message inspector for both the client and server ends)
  2. I add this attribute to the service interface, at the interface level, next to [ServiceContract]
  3. On the Web.config file, I add a line <serviceAuthorization principalPermissionMode="None" /> to the behavior definition

Please note that on my sample class, I am not currently sending the actual username, role and culture, but it is very easy to do, perhaps through message header properties.

When the web service receives the request, before it is actually forwarded to the apropriate method, it sets the Thread.CurrentPrincipal, Thread.CurrentCulture and Thread.CurrentUICulture properties.

Catch All Exceptions

As you may know, an exception is always thrown in the context of a running thread; what happens if there is no try...catch block protecting that thread? The exception is propagated to the application domain level, where, eventually, it will cause your application to crash.

Since you cannot be sure that all threads are running (and you may not want to do so, anyway) inside a try...catch block, there are two things you can do to, 1) at least, be notified when an exception occurs and 2) decide what to do when that happens. In a Windows Forms application, the System.Windows.Forms.Application class is where this is done.

The argument to Application.SetUnhandledExceptionMode can be one of:

  • UnhandledExceptionMode.Automatic: exception is caught in the Application.ThreadException handler, if there is no entry in the App.config or Web.config that disables it
    UnhandledExceptionMode.CatchException: exception is caught in the ThreadException handler
    UnhandledExceptionMode.ThrowException: exception is thrown, the ThreadException handler is ignored

See this example: 

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.Automatic);

Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);

void Application_ThreadException(Object sender, ThreadExceptionEventArgs e)

{

    //do something with e.Exception

}

If you don't have a Windows Forms application, but instead a console application or a Windows Service, you can still catch all exceptions at the application domain level:

AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

void CurrentDomain_UnhandledException(Object sender, UnhandledExceptionEventArgs e)
{

    //Object exception = e.ExceptionObject;
    //Boolean terminating = e.IsTerminating;
}

Finally, if you have an ASP.NET application, you add an event handler to the HttpApplication.Error event. This can be done in several ways:

1) Add an event handler to the Error event from anywhere (a page, a control, a module, etc): 

HttpContext.Current.ApplicationInstance.Error += new EventHandler(ApplicationInstance_Error);

void ApplicationInstance_Error(object sender, EventArgs e)
{

    //Exception ex = HttpContext.Current.Server.GetLastError();
    //HttpContext.Current.Server.ClearError();

}
2) Implement the Application_Error method on Global.asax.cs:

protected void Application_Error(Object sender, EventArgs args)

{

    //Exception ex = HttpContext.Current.Server.GetLastError();
    //HttpContext.Current.Server.ClearError();

}

3) Implement a custom IHttpModule and hook to the Error event (my favorite):

public class ErrorModule: IHttpModule

{

    public void Init(HttpApplication app)

    {

        app.Error += Application_Error;

    }

    void app_Error(object sender, EventArgs e)
    {
        //Exception ex = HttpContext.Current.Server.GetLastError();
        //HttpContext.Current.Server.ClearError();

    }

}

 

Posted: Mar 12 2009, 08:55 PM by Ricardo Peres | with 5 comment(s) |
Filed under: ,
ASP.NET Validation with the Enterprise Library Validation Block

The Enterprise Library comes with a custom ASP.NET validator, that gets validation from the metadata defined in your classes. If you have seen my previous post, you know how to add validation metadata to a POCO, usually a data transfer object. Basically, you either 1) add attributes to public properties and fields or 2) configure XML files. I'll stick to the first approach. What I'll show you next is how to do validation on web forms based on the validation metadata from a class. First, add a reference to the Microsoft.Practices.EnterpriseLibrary.Validation.Integration.AspNet assembly, and enter the following markup on you ASPX page:

<asp:TextBox runat="server" ID="text" />

<entlib:PropertyProxyValidator runat="server" ControlToValidate="text" SourceTypeName="SomeRequest, SomeAssembly" PropertyName="Text" />

<asp:Button runat="server" ID="button" CausesValidation="true" Text="Click Me" />

And that's it! The PropertyProxyValidator, in this case, will check the NotNullValidatorAttribute, StringLengthValidatorAttribute and ContainsCharactersValidatorAttribute that are applied to the Name property of the SomeRequest class.

The available validator attributes on assembly Microsoft.Practices.EnterpriseLibrary.Validation are:

- ContainsCharactersAttribute: Performs validation on strings by verifying if it contains a character set using the ContainsCharacters mode.

- DateTimeRangeValidatorAttribute: Performs validation on DateTime instances by comparing them to the specified boundaries.

- DomainValidatorAttribute: Validates an object by checking if it belongs to a set.

- EnumConversionValidatorAttribute: Validates a string by checking it represents a value for a given enum type.

- HasSelfValidationAttribute: Indicates the target type defines self validation methods.  

- IgnoreNullsAttribute: Indicates that a null value is to be allowed by the validator represented by the validation attributes for the language element this attribute is bound.

- NotNullValidatorAttribute: Logs a failure when validating a null reference.

- ObjectCollectionValidatorAttribute: Performs validation on collection objects by applying the validation rules specified for a supplied type to its members.

- ObjectValidatorAttribute: Performs validation on objects by applying the validation rules specified for a supplied type.

- PropertyComparisonValidatorAttribute: Performs validation by comparing the a value with the value of a property on the target object by using a specified comparison operation.

- RangeValidatorAttribute: Performs validation on instances by comparing them to the specified boundaries.

- RegexValidatorAttribute: Performs validation on strings by matching them to a Regex.

- RelativeDateTimeValidatorAttribute: Validates a DateTime value by checking it belongs to a range relative to the current date.

- SelfValidationAttribute: Marks a method as implementing self validation logic. Used in conjunction with HasSelfValidationAttribute.

- StringLengthValidatorAttribute: Performs validation on strings by comparing their lengths to the specified boundaries.

- TypeConversionValidatorAttribute: Validates a string by checking it represents a value for a given type.

- ValidatorCompositeAttribute: Indicates that the kind of composition to use when multiple ValidatorAttribute instances are bound to a language element.

It is very easy to define your own validators: just inherit from BaseValidationAttribute and implement your own validation logic.

The only drawback is that the page is always posted, that is, there is no JavaScript client validation, but you can place this inside an UpdatePanel, and it works just fine.

Validation of WCF Requests with the Enterprise Library Validation Block

In order to enable validation of the properties of a request message, you only need to add a [ValidationBehavior] attribute to your service interface, just next (or before) the [ServiceContract], and a [FaultContract(typeof(ValidationFault))] on the method declaration. The ValidationBehaviorAttribute and ValidationFault classes are defined in the Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF assembly and are part of the Validation Application Block of the Enterprise Library 4.1, more specifically, of the WCF integration module.

Here is an example:

[ServiceContract("http://someuri")]

[ValidationBehavior] 

public interface IRequest

{

    [OperationContract]

    [FaultContract(typeof(ValidationFault))]

    SomeResponse DoSomething(SomeRequest req);

} 

 In your request class (data transfer objects), you must then add validation attributes for each of the properties that you want to validate. For example:

[DataContract] 

public class SomeRequest

{

    [NotNullValidator(MessageTemplate = "{1} is null")]  //the property cannot be null

    [StringLengthValidator(4, 40, MessageTemplate = "The {1} must have between 4 and 40 characters")]  //must have between 4 and 40 characters

    [ContainsCharactersValidator("_/\\.;,:\'\"", ContainsCharacters = Any, Negated = true,  MessageTemplate = "The {1} contains invalid characters")]  //may not contain '_', '/', '\', '.', ';', ':', '\'' or "\"' characters

    public String Name

    {
        get; set;
    }   
}

Notice the {1} placeholder on the MessageTemplate property value: it is replaced by the current validating member name, in this case, the Name property. Valid placeholders depend on the actual validator used, but there are some common ones, which are:

  • {0}: The current value of the field or property
  • {1}: The name of the field or property
  • {2}: The tag name

Also, you can have resource values instead of hardcoded strings; instead of the MessageTemplate, add MessageTemplateResourceName and MessageTemplateResourceType, and the error string will be obtained from the resource named MessageTemplateResourceName from the assembly that contains the MessageTemplateResourceType type.

Your requests will then be automatically validated before they are transmitted, and, in the case of a validation exception, you will receive a FaultException<ValidationFault>, from which you will be able to extract validation errors, through the Details list property.

In the next post, I will explain how you can add validation to ASP.NET forms from the same metadata that is defined on the data transfer object class.

Bookmark and Share
More Posts Next page »