ASPHostCentral.com ASP.NET MVC Hosting BLOG

All about ASP.NET MVC 4.0 Hosting, ASP.NET MVC 3.0 Hosting and ASP.NET MVC Hosting articles

ASP.NET MVC 3 Hosting :: Analyzing AllowHtml Attribute in ASP.NET MVC 3.0

clock March 31, 2011 15:10 by author Administrator

Let's say we are creating a simple form in our ASP.NET MVC 3 web application and there is a Body field on the form where we want to allow HTML Tags.

If we do not disable request validation in some manner for this Body field, we will get the dreaded error - A potentially dangerous Request.Form value was detected from the client (Body = "<br>").


Request validation is a good thing since it keeps people from injecting script tags in our application for Cross-Site Scripting ( XSS ) attacks. However, in this case we want to disable request validation on the Body Field so we can put HTML in the body of our blog posts.

ValidateInput Attribute

In ASP.NET MVC 2 we used the ValidateInput Attribute on the action to disable request validation for the entire request

The downfall of this approach is that the ValidateInputAttribute disables request validation on all model properties, and we just want to disable request validation on a single property, called Body.

AllowHtmlAttribute in ASP.NET MVC 3

In ASP.NET MVC 3 we now have a property attribute that we can include on model properties to disable request validation on a property by property basis, called AllowHtmlAttribute. Instead of using the ValidateInputAttribute on the action, we turn off request validation just on Body by adding the [AllowHtml] Attribute to it:


This allows HTML for the Body Property, but does not allow HTML for the Title Property, which is what we want.

[Note: Briefly in ASP.NET MVC 3, before it was released, there existed a SkipRequestValidationAttribute. It no longer exists and has been renamed to AllowHtmlAttribute.]

   

Currently rated 1.5 by 4 people

  • Currently 1.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


ASP.NET MVC Hosting :: Working with Custom Authorisation in ASP.NET MVC Framework

clock March 30, 2011 16:20 by author Administrator

The whole advantage with MVC over webforms is extensibility at every point. Extensibility, Extensibility, Extensibility.

Authorization is a very important and every web project has there own needs and requirements. Full customisation is paramount.

Here I will show you a simple way to customise your authorization.

In MVC attributes are used to protect a controller method, so we to get started all we need to do is inherit from the AuthorizeAttribute class.

    public class CustomAuthorizeAttribute : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            string[] users = Users.Split(',');
            if (!httpContext.User.Identity.IsAuthenticated)
                return false;
            if (users.Length > 0 &&
                !users.Contains(httpContext.User.Identity.Name,
                    StringComparer.OrdinalIgnoreCase))
                return false;
            return true;
        }
    }

This is the basics. We can put any logic we like in here and all we have to do is return false if for whatever reason the user should not be authorized. Then all you need to do is decorate the controller method with the new attribute as below.

    [CustomAuthorize]
    public ActionResult Index()
    {
        return View();
    }

From this simple example we can expand it with custom Roles.

    public class CustomAuthorizeAttribute : AuthorizeAttribute
    {
        // the "new" must be used here because we are hiding
        // the Roles property on the underlying class
        public new SiteRoles Roles;
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext == null)
                throw new ArgumentNullException("httpContext");
            string[] users = Users.Split(',');
            if (!httpContext.User.Identity.IsAuthenticated)
                return false;
            SiteRoles role = (SiteRoles)httpContext.Session["role"];

            if (Roles != 0 && ((Roles & role) != role))
                return false;
            return true;
        }
    }

Where the SiteRoles class is defined as below.

    [Serializable]
    [Flags]
    public enum SiteRoles
    {
        User = 1 << 0,
        Admin = 1 << 1,
        Helpdesk = 1 << 2
    }

This can then be used be used as follows.
    [CustomAuthorize(Roles=SiteRoles.Admin|SiteRoles.HelpDesk)]
    public ActionResult Index()
    {
        return View();
    }

This will only allow the Admin and the Helpdesk Role access to the Index controller. If you don’t belong to one of these roles then you will be sent to the Login page.

The possibilities are really endless.

Happy coding.

Currently rated 2.1 by 12 people

  • Currently 2.083333/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


ASP.NET MVC 3.0 Hosting :: ASP.NET MVC 3.0 Validation and IValidatableObject

clock March 27, 2011 19:04 by author Administrator

I was working with ASP.NET MVC 3 validation today and was tickled to learn of the support for IValidatableObject. I mainly like to use the Enterprise Library Validation Application Block in my projects, but System.ComponentModel.DataAnnotations has come a long way in .NET Framework 4.

[Aside: Note in the following post I interchange “object“, “model“, and “self” validation.] IValidatableObject for Self Validation

For those of you who are familiar with Enterprise Library, you know it has two attributes that can be used for self validation of an object: HasSelfValidation and SelfValidation. The idea here is that there is model validation that may need to happen as a whole in addition to just property validation. Or, maybe validation is so complex that you don't want to use validation attributes and just want to do all validation “manually“ in a method. Self validation in Enterprise Library gives you opportunity to do this.

In the DataAnnotations world, you get this same kind of model or object validation by implementing IValidatableObject. ASP.NET MVC 3 has built-in support for IValidatableObject, so after propery validation it will fire off object validation if your object implements IValidatableObject. An example is shown below:

  

In this trivial example, I test to see if ConfirmPassword equals Password during registration using IValidatableObject. If they don't match, this is a validation error and I return a ValidationResult with the error. Pretty simple stuff.

IValidatableObject Doesn't Always Fire

There is a gotcha here that may not be obvious. IValidatableObject in ASP.NET MVC 3 will not fire if there are property-level errors. As I mentioned, ASP.NET MVC 3 property validation occurs before object validation. If there are property errors, ASP.NET MVC 3 by design will not fire IValidatableObject so as not to return false positives ( thanks to Brad Wilson of Microsoft for confirming this today ). For those of you who use EnterpriseLibrary and Self Validation where Enterprise Library combines the results, this might not seem obvious and could trip you up. ASP.NET MVC 3 does not combine the results.

In the case above, if the username is not provided ( yet as shown is required ), but both password and confirm password are provided, IValidatableObject will not fire and confirm the passwords match. IValidatableObject will not fire until all property-level validators validate, regardless if the properties play a part in the self-validation or not.

Personally I don't find this an issue, but just wasn't expecting it with all my years of Enterprise Library Validation Application Block experience.

A Note About ValidationAttribute in .NET Framework 4

Just a quick note about ValidationAttribute in System.ComponentModel.DataAnnotations. The ValidationAttribute in .NET 4 has been beefed up with a ValidationContext Class being passed in the validate method. ValidationContext contains the entire object being validated during property validation. You could create a custom validation attribute and place it on Password or ConfirmPassword for property comparison. That is certainly a workaround if you want to return the password comparison error regardless if other non-involved properties do not validate.

 

Currently rated 3.0 by 4 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


ASP.NET MVC 3 Hosting :: Working with ASP.NET MVC 3 RedirectPermanent syntax

clock March 23, 2011 16:42 by author Administrator

I am converting an ASP.NET WebForms website to ASP.NET MVC 3 for a client and by choice we are changing the URL structure as well. Because this may be a common situation, Microsoft introduced a new RedirectPermanent method on Response in ASP.NET 4.0.

If you take a peek at ASP.NET MVC 3, you will see new ActionResult Classes that do the same thing. You are probably familiar with Redirect, RedirectToAction, and RedirectToRoute, but now there are versions of these ActionResult Classes for permanent redirects: RedirectPermanent, RedirectToActionPermanent, and RedirectToRoutePermanent:  


Although out of the scope of this post, for search engine optimization benefits you will want to permanently redirect to the new location of a resource that has permanently moved by issuing an HTTP 301. The previous results only issue an HTTP 302, which means the resource has only temporarily moved.
  

Hope this helps.

Currently rated 1.5 by 26 people

  • Currently 1.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


ASP.NET MVC 3.0 Hosting :: How to Create and Maintain SessionLess Controllers in ASP.NET MVC 3

clock March 22, 2011 17:43 by author Administrator

One of the new features in ASP.NET MVC 3 is the [SessionState] Attribute that can be decorated on controllers. Using the attribute, you can completely turn on or off session state, adjust it to readonly, or make it required using a SessionStateBehavior Enum with the following choices:

- Default - The default ASP.NET logic is used to determine the session state behavior for the request. The default logic looks for the existence of marker session state interfaces on the IHttpHandler.
- Required - Full read-write session state behavior is enabled for the request. This setting overrides whatever session behavior would have been determined by inspecting the handler for the request.
- ReadOnly - Read-only session state is enabled for the request. This means that session state cannot be updated. This setting overrides whatever session state behavior would have been determined by inspecting the handler for the request.
- Disabled - Session state is not enabled for processing the request. This setting overrides whatever session behavior would have been determined by inspecting the handler for the request.

Turning off session state using the new SessionState Attribute in ASP.NET MVC 3 would look like this:



Obviously if session state is disabled we should no longer try to use the Session Property on the Controller as it will be null. Turning off session state and using the Session Property will give you the dreaded “object reference not set to an instance of object” error:




TempData and Session State

One thing that might not be so obvious is that the default provider for TempData uses session state ( SessionStateTempDataProvider ). Therefore if you turn off session state for the request but then try to access TempData you will get an error. Here is the use of TempData and the default SessionStateTempDataProvider:



and here is “The SessionStateTempDataProvider class requires session state to be enabled” exception you will receive:



If you still want to disable session state but use TempData, create a different provider for it that uses browser cookies for example. As it so happens, you can find a CookieTempDataProvider in ASP.NET MVC 3 Futures

Session State and Child Actions

The TempData scenario may be obvious, but this child action scenario may not be so obvious. Let's say we turned off session state in the parent controller and then we call a child action in a different controller using Html.RenderAction or Html.Action from within the view.



Does the child action have access to TempData and Session? The Child Controller looks like this:



Even though we did not disable session state on this controller, we won't have access to Session State or TempData in the child action because session state was disabled in the parent controller. The same errors mentioned above will occur.

Child Actions vs. Ajax Requests

Don't confuse ajax requests with child actions. I don't suspect you would, but the question has come up before. A child action is kicked off using Html.RenderAction or Html.Action in a view. Ajax requests coming from the browser are not child actions, but completely separate requests into the application. If you use jQuery within a view to grab data from the same action used above, called ChildAction, the action will have full access to session state since the request is no longer a child action but a normal request coming into the application.



I changed the controller to just grab the SessionId which will work fine:



Of course, this is true of any direct request to the action (e.g. http://.../child/childaction ). That request would no longer be a child action, but a regular ol' request. Since it is a regular request through this controller and session state has not been disabled using the [SessionState] Attribute or other means, session state is enabled and fully accessible.

Why Bother With SessionLess Controllers

The big question becomes why bother with SessionLess Controllers in ASP.NET MVC 3 if we have to tip-toe around TempData, ChildActions, etc?

Well, the use of session state has mainly been an issue of scalability, but things are changing a bit with heavy use of Ajax in the browser. One big drawback of using Session State is that concurrent requests to session state within the same session must be done one at a time when done with full read-write access. You cannot access session state in parallel with full read-write privileges as data corruption can occur. Therefore if you have multiple, concurrent requests from the same session they will need to be performed one at a time rather than in parallel.

When does this become a big deal? Mainly when concurrent ajax requests from the browser are firing off in the background in the same user session. If session state is enabled with full read-write privileges, those scripts cannot be run in parallel as they could corrupt session state. They will be executed one-at-a-time and possibly deteriorate the responsiveness of the UI.

A way to get multiple, concurrent requests in the same session to perform in parallel would be to completely disable session state or make it read only when it is indeed read only.

Conclusion

A new feature in ASP.NET MVC 3 is the ability to specify session state behavior on controllers using the new [SessionState] Attribute. Although there are some challenges, they can easily be managed if you need to squeeze out every ounce of scalability and responsiveness from your application.

Hope this helps.

Currently rated 1.7 by 31 people

  • Currently 1.709676/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


ASP.NET MVC 3 Hosting :: Things to know on MVC3's GlobalFilters and HandleErrorAttribute

clock March 21, 2011 18:20 by author Administrator

In MVC3 a GlobalFilterCollection has been added to the Application_Start. This allows you to register filters that will be applied to all controller actions in a single location. Also, MVC3 web applications now add an instance of HandleErrorAttribute to these GlobalFilters by default. This means that errors in the MVC pipeline will now be automatically handled by these attributes and never fire the HttpApplication's OnError event.

This is nice because it is another step away from the old ASP.NET way of doing things, and a step toward the newer cleaner MVC way of doing things.

Out With the Old

Our old HttpModule wired up to the HttpApplication's OnError event and used that to log unhandled exceptions in web applications. It didn't care if the error happened in or out of the MVC pipeline, either way it was going to bubble up and get caught in the module.

public virtual void Init(HttpApplication context)
{
   InsightManager.Current.Register();
   InsightManager.Current.Configuration.IncludePrivateInformation = true;
   context.Error += OnError;
}

private void OnError(object sender, EventArgs e)
{
   var context = HttpContext.Current;
   if (context == null)
       return;
   Exception exception = context.Server.GetLastError();
   if (exception == null)
       return;

   var abstractContext = new HttpContextWrapper(context);   InsightManager.Current.SubmitUnhandledException(exception, abstractContext);
}

However, now the MVC HandleErrorAttribute may handle exceptions right inside of the MVC pipeline, meaning that they will never reach the HttpApplication and the OnError will never be fired. What to do, what to do...

In With the New

Now we need to work with both the attributes and the HttpApplication, ensuring that we will catch errors from both inside and outside of the MVC pipeline. This means that we need to find and wrap any instances of HandleErrorAttribute in the GlobalFilters, and still register our model to receive notifications from the HttpApplications OnError event.

The first thing we had to do was create a new HandleErrorAttribute. Please note that this example is simplified and only overrides the OnException method. If you want to do this "right", you'll have to override and wrap all of the virtual methods in HandleErrorAttribute.

public class HandleErrorAndReportToInsightAttribute : HandleErrorAttribute
{
   public bool HasWrappedHandler
   {
       get { return WrappedHandler != null; }
   }

   public HandleErrorAttribute WrappedHandler { get; set; }
   public override void OnException(ExceptionContext filterContext)
   {
       if (HasWrappedHandler)
           WrappedHandler.OnException(filterContext);
       else
           base.OnException(filterContext);
       if (filterContext.ExceptionHandled)           InsightManager.Current.SubmitUnhandledException(filterContext.Exception, filterContext.HttpContext);   }
}

Next we needed to update our HttpModule to find, wrap, and replace any instances of HandleErrorAttribute in the GlobalFilters.

public virtual void Init(HttpApplication context)
{
   InsightManager.Current.Register();
   InsightManager.Current.Configuration.IncludePrivateInformation = true;
   context.Error += OnError;
   ReplaceErrorHandler();
}

private void ReplaceErrorHandler()
{
   var filter = GlobalFilters.Filters.FirstOrDefault(f => f.Instance is HandleErrorAttribute);
   var handler = new HandleErrorAndReportToInsightAttribute();
   if (filter != null)
   {
       GlobalFilters.Filters.Remove(filter.Instance);
       handler.WrappedHandler = (HandleErrorAttribute) filter.Instance;
   }
   GlobalFilters.Filters.Add(handler);
}

In Conclusion
Now when we register the InsightModule in our web.config, we will start capturing all unhandled exceptions again.

<configuration>
 <configSections>
   <section name="codesmith.insight" type="CodeSmith.Insight.Client.Configuration.InsightSection, CodeSmith.Insight.Client.Mvc3" />
 </configSections>
 <codesmith.insight apiKey="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" serverUrl="http://app.codesmithinsight.com/" />
 <system.web>
   <customErrors mode="On" />
   <httpModules>
     <add name="InsightModule" type="CodeSmith.Insight.Client.Web.InsightModule, CodeSmith.Insight.Client.Mvc3"/>
   </httpModules>
 </system.web>
</configuration>

Currently rated 3.2 by 6 people

  • Currently 3.166667/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


ASP.NET MVC 3 Hosting :: Problem in implementing IControllerActivator in ASP.NET MVC 3

clock March 14, 2011 17:16 by author Administrator

ASP.NET MVC 3 introduces two new interfaces to allow simple integration of IoC containers into the MVC pipeline, allowing many different types to be resolved using your IoC container of choice. These interfaces are IDependencyResolver and IControllerActivator but before you go ahead and implement both, let's take a look at whether they are both actually needed.

First some background

If you wanted to inject dependencies into your controllers in ASP.NET MVC 2, you were required to either implement IControllerFactory or subclass DefaultControllerFactory. Typically, you would pass your IoC container into the constructor of your custom controller factory and use it to resolve the controller in the CreateController method. You may also have added custom code in ReleaseController to clean up dependencies

This worked reasonably well, but in ASP.NET MVC 3 things have changed so we can use DI for a whole host of other objects such as filters and view engines

The new interface that we should implement is IDependencyResolver:


The important thing about your implementation of this interface is that it should return null if it cannot resolve a particular object. Below is a simple implementation using Unity:


When an MVC application starts for the first time, the dependency resolver is called with the following types in the following order:
- IControllerFactory
- IControllerActivator
- HomeController
….

If you do not implement IControllerFactory or IControllerActivator, then the MVC framework will try to get the controller from the DependencyResolver itself. As a side note, there is no need to worry about performance (regarding so many calls to the resolver) because MVC will only try to resolve theIControllerFactory and IControllerActivator once on startup and if no implementations are registered then it will subsequently always query the DependencyResolver first

The MVC framework goes on to try to resolve many other types which you probably have not implemented or registered with your IoC container, but as long as your dependency resolver returns null if the type is not registered, MVC will default back to the built-in implementations

If you did not implement your resolver to return null if a type is not registered then you will probably end up seeing an error similar to:

The current type, System.Web.Mvc.IControllerFactory, is an interface and cannot be constructed

The other important thing to note is that both methods on this interface take in the actual service type. This typically means that when you register your controllers with your IoC container, you should only specify the concrete type, not the IController, interface

i.e. using Unity as an example:


rather than:


Failing to register your controllers conrrectly and you will see

No parameterless constructor defined for this object

So at this stage, we have an implementation of IDependencyResolver and nothing else and yet our controller are all resolving correctly. It makes you wonder about whether IControllerActivator is really needed...

About IControllerActivator

IControllerActivator was introduced with ASP.NET MVC 3 to split the functionality of the MVC 2 controller factory into two distinct classes. As far as we can tell, this was done to adhere to the Single Responsibility Principle (SRP). So now in MVC 3, the DefaultControllerFactory outsources the responsibility of actually instantiating the controller to the controller activator. The single method interface is shown below:


If you implement this interface and register your activator with your IoC container, the MVC framework will pick it up and use it when trying to instantiate controllers, but you have to wonder why you would do this instead of just letting your dependency resolver do it directly. Brad Wilson to the rescue:

"If your container can build arbitrary types, you don't need to write activators. The activator services are there for containers that can't be arbitrary types. MEF can't, but you can add [Export] attributes to your controllers to allow MEF to build them..."

This means that if you are working with any competent IoC container* (Castle Windor, Unity, Ninject, StructureMap, Autofac et al), IControllerActivator is not needed and offers no benefit over allowing your DependencyResolver to instantiate your controllers.

* (With the exception of MEF which isn't an IoC container any way)

So we now know that we are probably not required to implement this interface, but are there any benefits to doing so? Something that we have seen mentioned (we cannot remember where) is that implementing IControllerActivator allows you you can provide a more meaningful error message if resolution fails. It is true that the message you would get otherwise (No parameterless constructor defined for this object) is not 100% clear, but we are not sure that this justifies another class just for this purpose. Surely, once you have seen this message, the next time you encounter, it you will immediately know what the problem is. Even if you do implement IControllerActivator, you will not have access to the (normally) detailed message that you IoC container provides when resolution fails, so you can do little more than say resolution failed - i don't know why.

Conclusion

So, should you implement IControllerActivator? Probably not. If you are using pretty much any well known IoC container, just implement IDependencyResolver and it will do everything for you. There is also no need for a custom implementation of IControllerFactory. If you are worried about the lack of release method on the dependency resolver, don't be. The worst case scenario requires a small change to the way that you are using your IoC container. Next time we will talk about how to make sure your dependency resolver plays nicely with IDisposable

           

Currently rated 1.9 by 21 people

  • Currently 1.857142/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


ASP.NET MVC 3 Hosting :: Working with ASP.Net MVC 3 Razor View Engine and Syntax Highlighting

clock January 25, 2011 14:38 by author Administrator

Today, we found a good answer on syntax highlighting for Razor. In the Visual Studio Gallery located at http://visualstudiogallery.msdn.microsoft.com/en-us/8dc77b9c-7c83-4392-9c46-fd15f3927a2e, a new Visual Studio extension has been recently added for a “Razor Syntax Highlighter”.



To leverage this new extension, we had to remove the editor mapping for .cshtml files in the Visual Studio Text Editor/File Extensions window and install the highlighter extension. As you see in the figure below, it worked great. This new extension uses the Razor Parser libraries to appropriately highlight the Razor code.


Figure 1 - Syntax Highlighting Visual studio 2010 Add-on

Unfortunately, this feature is offered as a Visual Studio Extension and hence is only available for paid-for Visual Studio 2010 editions.

Looking at the Razor Syntax, one can summarize it as a means to short-hand the <%= %> used in ASPX pages to designate code sections. For Razor, only a simple @ sign is used in-place of that bulky aforementioned code markup . Additionally, the Razor parser introduces helpful intelligence that makes the syntax even more user-friendly. For instance the following is a code block you would see in an ASPX page:

<%=if(true){%>
       <input type="hidden" value="istrue"/>
<%}%>  

The corresponding Razor block for this snippet would be:

@if(true){
       <input type="hidden" value="istrue"/>
}

The Razor syntax has simply “inferred” that the code will have a closing curly bracket without us having to apply any special markup tags to it. This further reduces the markup needed to accomplish the same task.

An important difference between Razor and ASPX View Engines is the absence of master pages for the earlier. Razor simply provides a _ViewStart.cshtml to bootstrap our application layout.

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

Latest Razor Beta does however support Partial rendering (RenderPartial) to explicitly render a Partial View as well as calling @RenderBody() which loads the actual view content to be served.

Next, we will be talking about creating an MVC project with dual support for ASPX/Razor View Engines as well as further explore the Razor syntax.

Currently rated 1.5 by 14 people

  • Currently 1.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


WCF Hosting :: Guidelines to WCF Versioning

clock January 9, 2011 16:01 by author Administrator

Overview

Services exist in order to serve external clients. They do so by exposing a wide range of external interfaces which are later used by the clients to interact with the service.

After initial deployment, and potentially several times during their lifetime, services may need to be changed for a variety of reasons, such as changing business needs, re-factorization of code, or to address other issues.

Each change introduces a new version of the service. Each new service version potentially introduces changes to the external interfaces exposed by the service.

Our goal, as developers, is to be able to freely change our service internals (and sometimes, when needed, external interfaces), and on the same time, allow existing and new clients to keep using the service.

In order to do so, we need to form a set of versioning guidelines.

This article will cover basic concepts related to versioning issues and will provide a set of guidelines which aim to provide a simple solution for the versioning problem domain.

All the information exists freely on the Internet. We didn’t invent anything new. We just gathered most of the information in one simple blog post, for your convenience.

A lot of the guidelines below were taken from an excellent set of MSDN articles:

http://msdn.microsoft.com/en-us/library/ms731060.aspx and http://msdn.microsoft.com/en-us/library/ms733832.aspx. These articles are very good reading material.  


Reduce the Problem Domain

Services interact with external services in many different ways. They can use WCF to send and receive information. They can connect to external databases directly (by using ADO.NET, for example) and many more.

Instead of forming a set of guidelines for each protocol, the simplest way is to reduce the problem domain to one protocol and use only one set of guidelines for this protocol.

For example, instead of connecting to a database directly, it is possible to create an abstraction layer on top of the database, which will expose WCF interface to the clients. This layer will be upgraded together with the database, creating a coupling between this layer and the database. The exposed WCF interface will follow the versioning guidelines that we will mention later, thus keeping all the clients compatible with the database service, even when it is being upgraded.

To sum it up, if you like the WCF versioning guidelines that we’ll mention later on, use WCF interfaces whenever possible to expose your service functionality.  


Versioning Terminology

Strict Versioning – In many scenarios when a change is required to an external interface, the service developer does not have control over the clients and therefore cannot make assumptions about how they would react to changes in the message XML or schema. The recommended approach in such scenarios is to treat existing data contracts as immutable and create new data contracts (with unique XML qualified names) instead.

Lax Versioning – In many other scenarios, the service developer can make the assumption that adding a new, optional member to the data contract will not break existing clients. This requires the service developer to investigate whether existing clients are not performing schema validation and that they ignore unknown data members. In these scenarios, it is possible to take advantage of data contract features for adding new members in a non-breaking way. WCF support Lax versioning: that is, they do not throw exceptions for new unknown data members in received data, unless requested otherwise.

When a connection is made between a client and a server of a different version, and a strict versioning is used, the client won’t be able to connect to a service of a different version. When lax versioning is used, the client will be able to connect and it is up to the developer to handle backward and forward compatibility.  


Client\Server Paradigm

In a client\server world, a client sends requests to a server, which, in turn, responds back to the client.

When versioning is introduced into the system, we may encounter the following scenarios:

Client and server use the same version.
Client is older than the server.
Client is newer than the server.

Each scenario should be handled separately, but there is one rule which applies to all: Newer element knows more than older element, therefore, newer elements should be the more proactive elements in the versioning game.

This means the following:

Client and server use the same version – No problem here. Communication will work as expected.

Client is older than the server – The server should support both older and current clients. When Lax Versioning is used, the server is allowed to add new data members and new operations (according to Lax guidelines which will be described later on). It must expose the same WCF service, on the same contract with the same name and namespace. When Strict Versioning is used, the server must expose (at least) two WCF services (and WCF contracts). The first is the new WCF service, on the new contract with a new namespace and name, and the rest are all the supported old WCF services with their original contacts, namespaces and names.

Client is newer than the server – The client must avoid using unsupported operations on an older server. When Lax versioning is used, the client is not allowed to call new operations (which don’t exist on the server side). When Strict versioning is used, the client must use a WCF endpoint which exposes a contract matching the one used by the server. In both approaches, the client must know the version of the server. This is performed by some kind a version discovery mechanism (more on this below).  

Note – If an element acts both as a client and as a server, it is very reasonable that it would suffer from both issues above, during the upgrade period. This means that it will probably have a local client newer than a remote server and a local server newer than a remote client. In these situations, each direction should be handled separately.    


Version Discovery Basics

When a client is newer than the server, as we already know, it must protect itself when communicating with an older server.

For example, if Lax versioning is used, the client should be responsible not to call new operations which are not supported by the server.

When Strict versioning is used, it should find a matching contract, support by the server, to communicate on.

In order to do that, the client must discover the server’s version. This is called Version Discovery.

There are several ways to discover the server’s version:

Get Version API – The server should expose its version somehow. The client should use this API to discover the server’s version before attempting to communicate with the server.

Fallback – The client tries to communicate with the server with the newest contract version known to the client, and falls back to older versions when the communication fails until it finds a contract version match (of course, this can only work with Strict versioning).

Configuration – The server version is stored somewhere in local configuration and the client can read it before attempting to connect to the server.   


Versioning Guidelines

So far we had a long introduction to the versioning world. It’s time to actually discuss some actual versioning guidelines.

First we will try to understand when to use Lax versioning and when to use Strict versioning. Later on, we will provide a set of guidelines for each versioning schema.

When building a complex system, involving multiple machines working together to expose one big external service, we can distinguish between two types of communication flows, inner communication an external communication.

Inner Communication – This covers all communication flows between the system’s machines. In such systems, usually, the developers have control on all components involved in the communication flows. Therefore, the natural versioning schema should be Lax versioning. As a reminder, Lax versioning can be used when we know something about the involved components and can enforce several assumptions on them. Of course, if we can’t make these assumptions, or if we require huge contract changes which can’t be covered by the Lax versioning guidelines (which will be covered later on), we can always fallback to Strict versioning.

External Communication – This covers all communication between internal endpoints (controlled by the system developers) to external endpoints (not controlled by the system developers, naturally). Since we don’t control one side of the conversation, Strict versioning is the only way to go. This means that whenever a new version is available, we create a new contract to represent it, while keeping the old contract intact. We must publish both the new contract and the old contract (or contracts, if we want to support several versions back) simultaneously. We might also consider providing some assistance in terms of providing some version discovery mechanisms. If clients are newer than the server, they will have to use one of the version discovery mechanisms to survive.   


Lax Versioning Guidelines

The guidelines are divided to service contract guidelines and data contract guidelines.

Lax Service Contract:

Namespace and Name – DO NOT change namespace or name between versions. Do not add namespace or name, if the contract didn’t have namespace or name in the previous version (unless you want to add the default namespace and name)

Operations Addition – Adding service operations exposed by the service can be considered as a non-breaking change because existing (older) clients need not be concerned about those new operations. Newer clients must use version discovery methods before contacting an older server and avoid calling new operations. If version discovery is impossible, adding operations is considered as a breaking change (strict).

Operations Removal – Removing operations is considered to be a breaking change and therefore, NOT ALLOWED. To make such a change, strict versioning should be used (define a new service contract and expose it on a new endpoint). It is still possible to remove operations, but this can be performed only after the versioning difference between a client and a server exceeds the maximum allowed by the system (for example, we support only one version back and we now upgrade to version N+2).

Operation Parameters Types – Changing parameter types or return types generally is considered to be a breaking change unless the new type implements the same data contract implemented by the old type. Other type changes are NOT ALLOWED. To make such changes, add a new operation to the service contract or use strict versioning.

Operation Parameters Addition/Removal – Adding or removing an operation parameter is a breaking change, therefore, it is NOT ALLOWED. To make such a change, add a new operation to the service contract or use strict versioning.

Operation Parameters Aggregation – It is recommended to use one aggregated data contract as an operation parameter, rather than separate multiple parameters. By using a data contract as aggregated parameter, while keeping the Lax guidelines for data contracts (see below), it is easier to keep an operation backward compatible. It is possible to change internal parameters without being limited to the above restrictions.

Fault Contracts – The list of faults described in a service’s contract is not considered exhaustive. At any time, an operation may return faults that are not described in its contract. Therefore changing the set of faults described in the contract is not considered a breaking change. For example, adding a new fault to the contract using the FaultContractAttribute or removing an existing fault from the contract is allowed.

Lax Data Contract:

Namespace and Name – DO NOT change namespace or name between versions. Do not add namespace or name, if the contract didn’t have namespace or name in the previous version (unless you want to add the default namespace and name)

Data Contract Names - In later versions, DO NOT change the data contract name or namespace. If changing the name or namespace of the type underlying the data contract, be sure to preserve the data contract name and namespace by using the appropriate mechanisms, such as the Name property of the DataContractAttribute.

Data Members Names – In later versions, DO NOT change the names of any data members. If changing the name of the field, property, or event underlying the data member, use the Name property of the DataMemberAttribute to preserve the existing data member name.

Data Members Types – In later versions, DO NOT change the type of any field, property, or event underlying a data member such that the resulting data contract for that data member changes. Keep in mind that interface types are equivalent to Object for the purposes of determining the expected data contract.

Data Members Addition – In later versions, new data members can be added. They should always follow these rules:

a. The IsRequired property should always be left at its default value of false.
b. If a default value of null or zero for the member is unacceptable, a callback method should be provided using the OnDeserializingAttribute to provide a reasonable default in case the member is not present in the incoming stream.
c. The Order property on the DataMemberAttribute should be used to make sure that all of the newly added data members appear after the existing data members. The recommended way of doing this is as follows: None of the data members in the first version of the data contract should have their Order property set. All of the data members added in version 2 of the data contract should have their Order property set to 2. All of the data members added in version 3 of the data contract should have their Order set to 3, and so on. It is permissible to have more than one data member set to the same Order number.

Data Members Order – In later versions, DO NOT change the order of the existing data members by adjusting the Order property of the DataMemberAttribute attribute.

Data Members Removal – DO NOT remove data members in later versions, even if the IsRequired property was left at its default property of false in prior versions.

Data Members IsRequired –
a. DO NOT change the IsRequired property on any existing data members from version to version.
b. For required data members (where IsRequired is true), DO NOT change the EmitDefaultValue property from version to version.

Branching – DO NOT attempt to create branched versioning hierarchies. That is, there should always be a path in at least one direction from any version to any other version using only the changes permitted by these guidelines. For example, if version 1 of a Person data contract contains only the Name data member, you should not create version 2a of the contract adding only the Age member and version 2b adding only the Address member. Going from 2a to 2b would involve removing Age and adding Address; Going in the other direction would entail removing Address and adding Age. Removing members is not permitted by these guidelines.

Known Types – You should generally not create new subtypes of existing data contract types in a new version of your application. Likewise, you should not create new data contracts that are used in place of data members declared as Object or as interface types. For example, in version 1 of your application, you may have the LibraryItem data contract type with the Book and Newspaper data contract subtypes. LibraryItem would then have a known types list that contains Book and Newspaper. Suppose you now add a Magazine type in version 2 which is a subtype of LibraryItem. If you send a Magazine instance from version 2 to version 1, the Magazine data contract is not found in the list of known types and an exception is thrown. Creating these new classes is allowed only when you know that you can add the new types to the known types list of all instances of your old application or if newer instances use version discovery and will not send new types to an old server.

Enumerations – DO NOT add or remove enumeration members between versions. You should also not rename enumeration members; unless you use the Name property on the EnumMemberAttribute attribute to keep their names in the data contract model the same.

Inheritance –

DO NOT attempt to version data contracts by type inheritance. To create later versions, either change the data contract on an existing type (Lax) or create a new unrelated type (Strict).

The use of inheritance together with data contracts is allowed, provided that inheritance is not used as a versioning mechanism and that certain rules are followed. If a type derives from a certain base type, do not make it derive from a different base type in a future version (unless it has the same data contract). There is one exception to this: you can insert a type into the hierarchy between a data contract type and its base type, but only if it does not contain data members with the same names as other members in any possible versions of the other types in the hierarchy. In general, using data members with the same names at different levels of the same inheritance hierarchy can lead to serious versioning problems and therefore, it is prohibited.

Collections – Collections are interchangeable in the data contract model. This allows for a great degree of flexibility. However, make sure that you do not inadvertently change a collection type in a non-interchangeable way from version to version. For example, do not change from a non-customized collection (that is, without the CollectionDataContractAttribute attribute) to a customized one or a customized collection to a non-customized one. Also, do not change the properties on the CollectionDataContractAttribute from version to version. The only allowed change is adding a Name or Namespace property if the underlying collection type’s name or namespace has changed and you need to make its data contract name and namespace the same as in a previous version.

Round Tripping – In some scenarios, there is a need to “round-trip” unknown data that comes from members added in a new version. For example, a “versionNew” service sends data with some newly added members to a “versionOld” client. The client ignores the newly added members when processing the message, but it resends that same data, including the newly added members, back to the versionNew service. The typical scenario for this is data updates where data is retrieved from the service, changed, and returned. If the data contract is expected to be used in a round tripping scenario, then starting with the first version of a data contract, always implement IExtensibleDataObject to enable round-tripping. If you have released one or more versions of a type without implementing this interface, it is usually recommended to implement it in the next version of the type.  


Strict Versioning Guidelines

Strict versioning guidelines are also divided into service contract and data contract guidelines, although they are very similar.

Strict Service Contract:

Namespace and Name – At least one of the namespace or name MUST be changed in later version, in order to break the contract compatibility. If the contract didn’t have namespace or name in previous version, namespace and name must be added to the contract (and must have different values than the default values)

Cascading Break – If a service contract exposes a data contract directly or via operations parameters or return value, and this data contract compatibility is broken (namespace or name replaced), then the service is also broken and MUST be treated as such, thus, a new contract should be created.

Immutability – When breaking a service contract, a new service contract MUST be created with a unique Namespace and Name, while the old contract MUST be kept intact and treated as immutable.

Strict Data Contract:

Namespace and Name – At least one of the namespace or name MUST be changed in later version, in order to break the contract compatibility. If the contract didn’t have namespace or name in previous version, namespace and name MUST be added to the contract (and must have different values than the default values)

Immutability – When breaking a data contract, a new data contract MUST be created with a unique Namespace and Name, while the old contract MUST be kept intact and treated as immutable.

Cascading Break – If a data contract is contained in a different data contract or exposed by a service contract directly or indirectly, and this data contract compatibility is broken (namespace or name replaced), then all contracts containing or exposing this data contract MUST be broken as well

Currently rated 1.5 by 6 people

  • Currently 1.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


ASP.NET MVC 3.0 Hosting :: Working with ServiceLocator in ASP.NET MVC 3.0

clock December 16, 2010 12:56 by author Administrator

For past couple of days we were checking out features of the new ASP.NET MVC Preview 3.There are couple of interesting new additions like integration with the new Razor viewengine,improvements in Model Validation,AJAX support and Dependency Injection. In this post we will discuss on, how ASP.NET MVC 3 has streamlined the ability to register/retrieve objects/services in a loosely coupled manner by incorporating support for the Common Service Locator framework.

What is Common Service Locator?Today we have many Inversion of Control/Dependency Injection Containers like NInject,StructureMap,Unity,.. etc in the .NET world.Most of these vary quite widely in terms of configuration and initialization/registration of the instances.But they provide more or less similar interface while resolving the dependencies and returning object instances.Common Service Locator framework extracts these commonalities out and provides an abstraction on top of these IoC/DI containers.This is now part of the Enterprise Library 5.0 and used in the Enterprise Library code to create/retrieve objects.Common Service Locator provides an interface IServiceLocator


It is quite evident from the method signatures that these are only related to retrieval of right object instances with proper resolution of the dependencies based upon different parameters.

Another important class related to the Common Service Locator is the ActivationException which needs to be thrown whenever there is exception in instantiating the objects /resolving the dependencies.

We were planning to use StructureMap as the DI Container and a StructureMap Adapter for Service Locator was available in Codeplex but that seemed far from complete.

So we went ahead to write few lines of code and develop a service locator which will use StructureMap as the DI container as shown below:

 

This class accepts an instance of the StructureMap.Container in the constructor and uses it to resolve dependencies and instantiate objects.In the implementation of the IServiceLocator methods we have to just map them suitably to StructureMap.Container.GetAllInstances and StructureMap.Container.GetInstance methods (and their overloads).The code which depends on IServiceLocator will perform exception handling based on ActivationException class whereas StructureMap raises StructureMap.StructureMapException in most of the cases.So we need to catch StructureMapException in this class and throw a ActivationException.The complete code is given below:

 

So we have our Service Locator class ready.In next part of the post we will see how we can plug this into the ASP.NET MVC 3.0 Framework

Currently rated 1.9 by 18 people

  • Currently 1.888889/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


ASP.NET MVC Hosting

ASPHostCentral is a premier web hosting company where you will find low cost and reliable web hosting. We have supported the latest ASP.NET 4.5 hosting and ASP.NET MVC 4 hosting. We have supported the latest SQL Server 2012 Hosting and Windows Server 2012 Hosting too!


Sign in