Windows 2012 Hosting - MVC 6 and SQL 2014 BLOG

Tutorial and Articles about Windows Hosting, SQL Hosting, MVC Hosting, and Silverlight Hosting

Cloud Hosting - Cloud Computing Advantages

clock January 30, 2013 09:39 by author andy_yo

Cloud computing is a disruptive technology that is changing the way enterprises look to meet their IT hardware and software requirements. Cloud computing is a mix of the latest ideas, technology and delivery models including Infrastructure as a Service (IaaS), Platform as a Service (PaaS) and Software as a Service (SaaS), and other models in the IT sector that use the Internet for delivering services to the user. Users can access infrastructure namely, the servers, software, and data center space or network equipment; the required computing platform and solution stack for a building an application, covering the cycle of development, testing, deployment, hosting and maintenance; and also most of the regular software applications; these are all provided cheaply and efficiently over the Internet.

About ASPHostPortal.com

ASPHostPortal.com is Microsoft No #1 Recommended Windows and ASP.NET Spotlight Hosting Partner in United States. Microsoft presents this award to ASPHostPortal.com for ability to support the latest Microsoft and ASP.NET technology, such as: WebMatrix, WebDeploy, Visual Studio 2012, ASP.NET 4.5, ASP.NET MVC 4.0, Silverlight 5 and Visual Studio Lightswitch. Click here for more information

Some of the benefits of the Cloud are listed below:

Decreased Costs: The Cloud eliminates the need for each user to invest in stand-alone servers or software that is capital intensive, but under-utilized most of the time. As technological innovations take place, these resources become obsolete and must be replaced with the latest in order to ensure operational efficiency – requiring more capital investment – and the cycle repeats. The Cloud eliminates the need for such ‘replacement’ capital expenditure.
Many users share a Cloud leading to distributed costs and economies of scale as resources including real estate, bandwidth, and power, are centralized. The enterprise also saves on overheads such as management costs, data storage costs, costs of software updates, and quality control and is able to use Cloud services at economical rates.

Scalability and Speed: Enterprises no longer have to invest time in buying and setting up the hardware, software and other resources necessary for a new application. They can quickly scale up or scale down their usage of services on the Cloud as per market demands, during hours of maximum activity, while launching sales campaigns, etc. Cloud services are most usually reliable, since many service providers have data centers in multiple locations for keeping the processing near users.

Innovation: Enterprises can focus on innovation, as they do not have to own or manage resources. Cloud computing facilitates faster prototype development, testing and validation. Research and development projects or activities where users have to collaborate for a task/project are especially benefited.

Convenience: Sharing of infrastructure and costs ensures low overheads and immediate availability of services. Payments are billed on the basis of actual consumption only. Details of billing are made available by the service provider also serves to check costs.
Other than an Internet-connected device, special equipment or specially-trained manpower is not needed. One-off tasks can be performed on the Cloud. High-speed bandwidth ensures real-time response from infrastructure located at different sites.

Location Independence: Service providers can set up infrastructure in areas with lower overheads and pass on the benefit. They can set up multiple redundant sites to facilitate business continuity and disaster recovery. This helps the enterprise cut costs further.

Optimal Resource Utilization: Servers, storage and network resources are better utilized as the Cloud is shared by multiple users, thus cutting down on waste at a global level. Cloud computing is more environment-friendly and energy efficient. Down-time is cut and optimization of resources across enterprises on the Cloud is achieved.

Flexibility: Users can opt out at will and thus gain a high level of operational flexibility.  The services are covered by service level agreements and the service provider is required to pay a penalty if the quality agreed to is not provided.

Device Independence: Applications provided through the Cloud can be accessed from any device – a computer, a smartphone, an iPad, etc. Any device that has access to the Internet can leverage the power of the Cloud.



ASP.NET MVC Hosting - ASPHostPortal :: Make a Captcha Image Validation with Jquery and MVC

clock January 28, 2013 09:37 by author Jervis

The code snippets below show how to use a simple class. To create a validation mechanism via captcha in ASP.Net , using Jquery and MVC. 

Using the code  

The code consists of two parts that work together to make the code work.

The first in javascript that runs on the client and should be placed on the page header, is responsible for making the request to the server. 

Note: I must remember that this javascript code requires Jquery, which can be downloaded here

   <script type="text/javascript" language="javascript">
        $(document).ready(function () {
            loadCaptcha();
        });
        function loadCaptcha() {
            $.ajax({
                type: 'GET', url: 'Home/generateCaptcha',
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                cache: false,
                success: function (data) { $("#m_imgCaptcha").attr('src', data); },
                error: function (data) { alert("Error while loading captcha image") }
            });
        }
    </script>

The second in C# runs  on the server.

That Receives the request from the page, generates an image with the specified text, this text can be generated by a function embedded in class or can be specified by the developer. The text is saved in the Session and is used to validate the data entered by the user. 

public ActionResult generateCaptcha()
        {
            System.Drawing.FontFamily family = new System.Drawing.FontFamily("Arial");
            CaptchaImage img = new CaptchaImage(150, 50, family);
            string text = img.CreateRandomText(4) + " " + img.CreateRandomText(3);
            img.SetText(text);
            img.GenerateImage();
            img.Image.Save(Server.MapPath("~") + this.Session.SessionID.ToString() + ".png", System.Drawing.Imaging.ImageFormat.Png);
            Session["captchaText"] = text;
            return Json(this.Session.SessionID.ToString() + ".png?t=" + DateTime.Now.Ticks, JsonRequestBehavior.AllowGet);
        }

Here is an example of a captcha image generated using this code.

Advantages of use

You know what's running on your server.

No special settings are needed.

Is not necessary use third party components that can fail.

It is fully customizable. 

 



ASP.NET MVC 4 Hosting - ASPHostPortal :: Getting WebApi and Areas to play nicely ASP.NET MVC 4

clock January 21, 2013 07:08 by author Jervis

In this blog, I discuss these limitations and present a possible solution.

Background

The WebApi and Areas features play an important role in the project I am currently working on. In this project, a web application is developed for multiple types of end-users. Areas are used to create separate frontends for each type of end-user. WebApi is used as part of an interaction framework (knockoutjs) that enriches the user experience. Below is a list of relevant design decisions that were made:

- The main MVC application resides in the root of the solution.
- All administrator functionality resides in a separate area.
- Each external party has its own area.
- Each area, including the root, constitutes a well separated functional block. Functionality from one area may not be exposed to another area. This is to prevent unauthorized access of data.
- Each area, including the root, has its own RESTfull API (WebApi).

During the development of this web application, I encountered an important limitation of WebApi when used in conjunction with Areas.

Routing and WebApi

Both regular and WebApi calls use ASP.NET MVC’s routing mechanism to translate HTTP requests to the appropriate controller action. However, only regular calls support areas, while WebApi calls are “arealess”. As a result, WebApi controllers in different areas are actually accessible from all areas. Additionally, having multiple WebApi controllers with identical names in different areas will produce an exception:

Multiple types were found that match the controller named ‘clients’. This can happen if the route that services this request (‘api/{controller}/{id}’) found multiple controllers defined with the same name but differing namespaces, which is not supported.

The request for ‘clients’ has found the following matching controllers:
MvcApplication.Areas.Administration.Controllers.Api.ClientsController
MvcApplication.Controllers.Api.ClientsController

The error message pretty much sums up the problem: ASP.NET MVC 4 RC does not support the partitioning of WebApi controllers across areas.

IHttpControllerSelector

The culprit is the DefaultHttpControllerSelector which is ASP.NET MVC’s default implementation of the IHttpControllerSelector interface. This class is responsible for selecting the appropriate IHttpController (the interface implemented by ApiController), when provided with a HTTP request message. At the heart of the DefaultHttpControllerSelector lies the HttpControllerTypeCache. This class runs through all assemblies that are used by the application and caches all types that implement the IHttpController. The SelectController method of the DefaultHttpControllerSelector uses this cache to lookup a matching type for the given controller name. This operation can end in three different manners:

- No matching types were found, which results in an HttpStatus.NotFound (404).
- One matching type was found, which is returned by the method and ASP.NET MVC continues to process the request.
- Multiple matches were found, which results in an exception similar to one displayed earlier.

In search for a solution

Fortunately, through the power of Inversion of Control, developers can inject their own implementation of IHttpControllerSelector. In a related blog by Andrew Malkov, he attempts to tackle the problem by creating a custom implementation called AreaHttpControllerSelector.

This class allows area specific WebApi controllers to co-exist, provided one makes a minor modification to the WebApi routes. In order to function, a default route parameter called “area” must be added to the HttpRoute definition in the AreaRegistration file.

1              context.Routes.MapHttpRoute(
2                  name: "Administration_DefaultApi",
3                  routeTemplate: "Administration/api/{controller}/{id}",
4                  defaults: new { area = "Administration", id = RouteParameter.Optional }
5              );

Unfortunately, adding this extra parameter introduces a new limitation: Querystring parameters on WebApi calls no longer function. E.g. GET /Administration/api/clients will work, but GET /Administration/api/clients?firstname=john will result in a 404.

Part of the problem lies in the manner in which AreaRegistration is used to define routes. Consider the AdministrationAreaRegistration below:

1              public class AdministrationAreaRegistration : AreaRegistration
2              {
3                  public override string AreaName
4                  {
5                      get
6                      {
7                          return "Administration";
8                      }
9                  }
10          
11               public override void RegisterArea(AreaRegistrationContext context)
12               {
13                   context.Routes.MapHttpRoute(
14                       name: "Administration_DefaultApi",
15                       routeTemplate: "Administration/api/{controller}/{id}",
16                       defaults: new { id = RouteParameter.Optional }
17                   );
18          
19                   context.MapRoute(
20                       "Administration_default",
21                       "Administration/{controller}/{action}/{id}",
22                       new { action = "Index", id = UrlParameter.Optional }
23                   );
24               }
25           }

The first route defines how ApiContollers can be reached, while the second route defines how regular controllers can be reached. Both registrations use a different method for registering the route in order to differentiate between normal calls and WebApi calls. Routes registered through MapHttpRoute are meant for WebApi controllers while routes registered through MapRoute are meant for regular controllers.

Note that MapHttpRoute is called on the Routes collection, whereas MapRoute is called on the AreaRegistrationContext itself. This implies that there is a difference between the default MapRoute and the one provided by the AreaRegistrationContext.

After digging through the sourcecode of ASP.NET MVC, I found that the most notable difference is that the MapRoute of AreaRegistrationContext incorporates the AreaName into the route’s metadata. Specifically, the value of the AreaName property is added to the route’s DataTokens.

Solution – Part 1

I created a MapHttpRoute extension method for the AreaRegistrationContext that performed a similar operation as the AreaRegistrationContext.MapRoute method.

1              public static class AreaRegistrationContextExtensions
2              {
3                  public static Route MapHttpRoute(this AreaRegistrationContext context, string name, string routeTemplate)
4                  {
5                      return context.MapHttpRoute(name, routeTemplate, null, null);
6                  }
7             
8                  public static Route MapHttpRoute(this AreaRegistrationContext context, string name, string routeTemplate, object defaults)
9                  {
10                   return context.MapHttpRoute(name, routeTemplate, defaults, null);
11               }
12          
13               public static Route MapHttpRoute(this AreaRegistrationContext context, string name, string routeTemplate, object defaults, object constraints)
14               {
15                   var route = context.Routes.MapHttpRoute(name, routeTemplate, defaults, constraints);
16                   if (route.DataTokens == null)
17                   {
18                       route.DataTokens = new RouteValueDictionary();
19                   }
20                   route.DataTokens.Add("area", context.AreaName);
21                   return route;
22               }
23           }

To use the new extension method, remove the Routes property from the call chain:

1              context.MapHttpRoute(
2                name: "Administration_DefaultApi",
3                routeTemplate: "Administration/api/{controller}/{id}",
4                defaults: new { id = RouteParameter.Optional }
5              );

Now both the regular routes and the WebApi routes have knowledge of their corresponding area.

Solution – Part 2

The second part of the solution is to create an implementation of IHttpControllerSelector that actually uses the area name. I took the AreaHttpControllerSelector class from Andrew Malkov’s blog post and used it as a base for my own solution.

1              namespace MvcApplication.Infrastructure.Dispatcher
2              {
3                  using System;
4                  using System.Collections.Concurrent;
5                  using System.Collections.Generic;
6                  using System.Globalization;
7                  using System.Linq;
8                  using System.Net.Http;
9                  using System.Web.Http;
10               using System.Web.Http.Controllers;
11               using System.Web.Http.Dispatcher;
12          
13               public class AreaHttpControllerSelector : DefaultHttpControllerSelector
14               {
15                   private const string AreaRouteVariableName = "area";
16          
17                   private readonly HttpConfiguration _configuration;
18                   private readonly Lazy<ConcurrentDictionary<string, Type>> _apiControllerTypes;
19          
20                   public AreaHttpControllerSelector(HttpConfiguration configuration)
21                       : base(configuration)
22                   {
23                       _configuration = configuration;
24                       _apiControllerTypes = new Lazy<ConcurrentDictionary<string,
Type>>(GetControllerTypes);
25                   }
26          
27                   public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
28                   {
29                       return this.GetApiController(request);
30                   }
31          
32                   private static string GetAreaName(HttpRequestMessage request)
33                   {
34                       var data = request.GetRouteData();
35                       if (data.Route.DataTokens == null)
36                       {
37                           return null;
38                       }
39                       else
40                       {
41                           object areaName;
42                           return data.Route.DataTokens.TryGetValue(AreaRouteVariableName, out areaName) ? areaName.ToString() : null;
43                       }
44                   }
45          
46                   private static ConcurrentDictionary<string, Type> GetControllerTypes()
47                   {
48                       var assemblies = AppDomain.CurrentDomain.GetAssemblies();
49          
50                       var types = assemblies
51                           .SelectMany(a => a
52                               .GetTypes().Where(t =>
53                                   !t.IsAbstract &&
54                                   t.Name.EndsWith(ControllerSuffix, StringComparison.OrdinalIgnoreCase) &&
55                                   typeof(IHttpController).IsAssignableFrom(t)))
56                           .ToDictionary(t => t.FullName, t => t);
57          
58                       return new ConcurrentDictionary<string, Type>(types);
59                   }
60          
61                   private HttpControllerDescriptor GetApiController(HttpRequestMessage request)
62                   {
63                       var areaName = GetAreaName(request);
64                       var controllerName = GetControllerName(request);
65                       var type = GetControllerType(areaName, controllerName);
66          
67                       return new HttpControllerDescriptor(_configuration, controllerName, type);
68                   }
69          
70                   private Type GetControllerType(string areaName, string controllerName)
71                   {
72                       var query = _apiControllerTypes.Value.AsEnumerable();
73          
74                       if (string.IsNullOrEmpty(areaName))
75                       {
76                           query = query.WithoutAreaName();
77                       }
78                       else
79                       {
80                           query = query.ByAreaName(areaName);
81                       }
82          
83                       return query
84                           .ByControllerName(controllerName)
85                           .Select(x => x.Value)
86                           .Single();
87                   }
88               }
89          
90               public static class ControllerTypeSpecifications
91               {
92                   public static IEnumerable<KeyValuePair<string, Type>> ByAreaName(this IEnumerable<KeyValuePair<string, Type>> query, string areaName)
93                   {
94                       var areaNameToFind = string.Format(CultureInfo.InvariantCulture, ".{0}.", areaName);
95          
96                       return query.Where(x => x.Key.IndexOf(areaNameToFind, StringComparison.OrdinalIgnoreCase) != -1);
97                   }
98          
99                   public static IEnumerable<KeyValuePair<string, Type>> WithoutAreaName(this IEnumerable<KeyValuePair<string, Type>> query)
100                 {
101                     return query.Where(x => x.Key.IndexOf(".areas.", StringComparison.OrdinalIgnoreCase) == -1);
102                 }
103        
104                 public static IEnumerable<KeyValuePair<string, Type>> ByControllerName(this IEnumerable<KeyValuePair<string, Type>> query, string controllerName)
105                 {
106                     var controllerNameToFind = string.Format(CultureInfo.InvariantCulture, ".{0}{1}", controllerName, AreaHttpControllerSelector.ControllerSuffix);
107        
108                     return query.Where(x => x.Key.EndsWith(controllerNameToFind, StringComparison.OrdinalIgnoreCase));
109                 }
110             }
111         }

If you want to learn more about the technical details of the solution, I suggest you read Andrew’s excellent blog post first. The most significant modifications are:

Changed the GetAreaName method in order to retrieve the area name from the DataTokens property rather than the RouteData.

Added support for “arealess” WebApi controllers (e.g. those that reside in the root) to the GetControllerType method.

Removed the fallback mechanism from the SelectController method. The original implementation would call the SelectController method of the base-class in case GetControllerType failed to produce a result. I preferred an approach where the responsibility of successful controller selection resided in AreaHttpControllerSelector.

Finally, to inject the new AreaHttpControllerSelector class, the following line must be added to the Application_Start method in the Global.asax.cs

1              GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector), new AreaHttpControllerSelector(GlobalConfiguration.Configuration));

After these modifications everything worked as expected!

 



About ASPHostPortal.com

We’re a company that works differently to most. Value is what we output and help our customers achieve, not how much money we put in the bank. It’s not because we are altruistic. It’s based on an even simpler principle. "Do good things, and good things will come to you".

Success for us is something that is continually experienced, not something that is reached. For us it is all about the experience – more than the journey. Life is a continual experience. We see the Internet as being an incredible amplifier to the experience of life for all of us. It can help humanity come together to explode in knowledge exploration and discussion. It is continual enlightenment of new ideas, experiences, and passions


Author Link


Corporate Address (Location)

ASPHostPortal
170 W 56th Street, Suite 121
New York, NY 10019
United States

Sign in