Archive for the 'C#' Category

Creating a Custom DNN Module and Integrating Captcha

I recently had a customer request to add a Contact Us form to their DNN installation. It’s something I hadn’t done for a while. In fact, it’s been so long that the language has changed. Last time I played around behind the scenes on DNN (or DotNetNuke as it then was), the language was VB only – this time, the installation is C#. It turned out to be a lot simpler than it was back then, and also gloriously easy to add captcha – another of the customer requirements, as they’re tired of receiving spam from online forms.

I’m guessing that this is something a number of the readers of this blog might need to do some time, so I thought I’d share the easy way to build a DNN form module that includes a captcha.

Getting DNN to Create the Module

The first step is to get DNN to create the Module for you. You’re going to do this twice – once on your development machine, and again on the live site.

I ran the development copy of the site from Visual Studio 2012 and logged in as the host. Then I did the following:

  1. Go to Host | Extensions

  1. On the Extensions page, select “Create New Module”

  1. In the dialog, there will initially be a single dropdown for “Create Module From”. Select “New”

  2. This will then open up more fields, and allow you to get DNN to do the hard work for you. You want to
    1. Define an owner folder – in this case I went with my company name as the outer folder
    2. Create a folder for this specific module – I’m creating a contact us form, so ContactUs seemed like a sensible name
    3. Come up with a name for the file and the module – I went with Contact for both, to distinguish the Contact module from the ContactUs folder.
    4. Provide a description so you’ll recognize what it is
    5. Tick the ‘create a test page’ option so you can check everything was wired up correctly

You can now close your browser and take a look at the structure DNN has created. We have a new folder structure underneath DesktopModules  – an outer Time2yak folder, and a nested ContactUs folder, complete with a Contact.ascx file:

If you open the web user control in the designer, this is what you get:

That’s given us a good starting point – but the first thing we’re going to do is delete the Contact.ascx user control. Just make sure you copy the value of the inherits attribute from the DotNetNuke.Entities.Modules.PortalModuleBase directive at the top of the ascx page before you delete it:

Creating the Web User Control

Now we’re going to create our own user control with a separate code behind page.

  1. Delete Contact.ascx and then right click on the folder and create a new Web User Control called Contact. This will recreate the ascx file, but this time with a code-behind file

  1. Change the definition of the code behind file so that it Inherits from DotNetNuke.Entities.Modules.PortalModuleBase (which is why you copied it).
  2. Now all you need to do is code the user control to do whatever you want it to do, just like any other ASP.NET Web Forms user control. I added a simple contact form with textboxes, labels, validation etc.:

  1. I then used DNN’s built in Captcha control. It’s easy to use, provided you don’t mind working in source view, rather than design (actually, I prefer source view, so this works well for me). You just need to
    1. Register the Control

    2. Add it to the page

    3. Check the IsValid property in the code behind (note the use of Portal.Email to get the admin email address).

Import the Module to the live site

This is the easiest part of all. Just use the same steps to create the module on the live server that you did in development, and then copy your version of contact.ascx over the version on the live site.  You now have the module in place and it appears in the modules list and can be added to any page you want:

And when you add it to the page, you have a Contact Us form with a captcha, developed as a DNN module:

The only other step is to use DNN to create the ThankYou.aspx page that the form passes through to – and that’s just a matter of using the CMS and doesn’t involve any coding.

Kevin Rattan

For other related information, check out these courses from Learning Tree:

Building ASP.NET Web Applications: Hands-On

Get 50% OFF Select Learning Tree Courses by Joining the New My Learning Tree Community!

We have some more exciting news to share!

Instantly receive 50% OFF select Learning Tree courses when you join the new My Learning Tree Community.

Free membership includes: weekly updates of our 50% OFF course events, access to our instructor blogs, podcasts, white papers, course materials and other valuable resources.

Feel free to drop us a comment below if you have any questions — or, follow us:

Facebook
Twitter
LinkedIn
Google+

Join today by clicking here.

Creating a Custom Web API Model Binder

When the Web API accepts a request from a client to a service, the Web API attempts to map the data in the request to a .NET object to pass as a parameter to the appropriate method in the service–a process called model binding. I’m consistently amazed at how powerful model binding is. But, as powerful as the process is, it is possible to have a request that defeats model binding. Fortunately, that doesn’t mean that you’re defeated: you can create your own model binder that will map the data in an incoming request to the .NET object that your service method accepts as a parameter.

As an example for creating a model binder, I first need a request that defeats the default model binder–not easy to do because the model binder is so powerful. So, I cheated: I created an ASP.NET WebForm with three TextBoxes (with IDs of CustomerID, CompanyName, and City), a Label (ID of Messages), and a GridView (GridView1). I then posted that whole form to a Web API service using a JavaScript function attached to the OnClientClick event of an ASP.NET Button on the WebForm:

<asp:Button ID="PostButton" runat="server" Text="Update" OnClientClick="return UpdateCustomer();" />

The JavaScript function serializes the form and posts it to a Web API method at “<server/site name>/CustomerManagement” (the function returns false to prevent the ASP.NET Button from posting the form back to the server):

function UpdateCustomer() {
    $.post('CustomerManagement', $('#form1').serialize())
     .success(function (data, status) {
              $("#Messages").text(status);                        
     })
     .error(function (data, msg, detail) {
        alert(data + '\n' + msg + '\n' + detail)
     });
   return false;
}

I defined the the Web API method that will process the request to accept the request’s values in the properties of a class I created and called CustomerOrderDTO:

public HttpResponseMessage Post(CustomerOrderDTO custOrderDTO)
{

And here’s the first version of that CustomerOrderDTO class  with properties whose names match the Ids on the TextBoxes:

public class CustomerOrderDTO
{
  public string CustomerID { get; set; }
  public string CompanyName { get; set; }
  public string City { get; set; }
}

And, amazingly, this works! Model binding instantiates a CustomerOrderDTO object and fills the properties on the object with the matching values from the TextBoxes on the form. But what about the GridView in my WebForm?

Defeating the Default Model Binder

The first thing to recognize is that, normally, the data on the GridView isn’t sent in the request to the Service when I use the serialize method in my JavaScript function: in Display mode, the GridView is just text in an HTML table which the serialize method ignores. However, if the user puts a row in the GridView into Edit mode, the values in the row are displayed in TextBoxes–and the values from those TextBoxes are included in the serialized request sent to the service.

What I would like is to use a DTO class like the following, where I want the OrderId, OrderDate, and RequiredDate properties to hold the values from the row in the GridView that the user has put in Edit mode:

public class CustomerOrderDTO
{
  public string CustomerID { get; set; }
  public string CompanyName { get; set; }
  public string City { get; set; }
  public string OrderId {get; set;}
  public DateTime OrderDate { get; set; }
  public DateTime RequiredDate { get; set; }        
}

The model binder can’t do that and looking into the request shows why. The content of the request sent by my JavaScript code looks something like this (the ellipses mark parts of the request that I’ve omitted to focus on what matters to this example):

__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=m0iKSCROBo3ZT9WDkCx8znpAEM2kV5SIg9Gd
OHK%2Bdy...Khbx%2BA%3D%3D&CustomerID=ALFKI&CompanyName=PH%26V+Information+Servic
es&City=&GridView1%24ctl05%24ctl02=10835&GridView1%24ctl05%24ctl03=ALFKI&GridVie
w1%24ctl05%24ctl04=1%2F15%2F1998+12%3A00%3A00+AM&GridView1%24ct...

If you look carefully you can see the TextBoxes’ names with their values in the request, with each name/value pair separated by an equals sign and ending with an ampersand (e.g. CustomerID=ALFKI&CompanyName=…). You can also find the values from the row of the GridView that’s being sent to the service with its TextBoxes’ names and their values though those names and values aren’t as obvious:

...&GridView1%24ctl05%24ctl02=10835&GridView1%24ctl05%24ctl03=...

The GridView’s TextBoxes have names that are auto-generated by the GridView control and look like “GridView1%24ctl05%24ctl02” (that’s the name of TextBox in the fifth row, second column). These names, in addition to being opaque, will change depending on which row the user has put in Edit mode (for instance, the equivalent TextBox from the fourth row has the name GridView1%24ctl04%24ctl02). The default model binding provided with the Web API can’t match those changing names to properties on a class. However, if I create my own model binder, I can make this work.

Creating a Custom Model Binder

The first step in creating a custom model binder is to add a class to your project and have the class implement the IModelBinder interface (for the following code to work, you’ll need using statements for System.Web.Http.Controllers, System.Web.Http.ModelBinding, System.Web.Http.ValueProviders, and System.Net). The interface will give add a single method to your model binding class, called BindModel:

public class CustomerOrderModelBinder: IModelBinder
{
  public bool BindModel(System.Web.Http.Controllers.HttpActionContext actionContext, ModelBindingContext bindingContext)
  {

The BindModel method will be called by the Web API as it attempts to map the incoming request to my CustomerOrderDTO object (or will called be after I do a little more work–see the end of this post). The two parameters passed to the BindModel method give you access to all the data that you might need to retrieve the values in the request and move them to the object that your service method is accepting–but I’ll use very little of those features in this example. There are also a couple of ways that you can, after extracting values from the request sent to the service, pass those values to the service’s method. For this example, I’ll just instantiate my CustomerOrderDTO object and put it into the Model property of the ModelBindingContext object that’s passed as a parameter to the BindModel method as the first steps in my BindModel code:

CustomerOrderDTO coDto = new CustomerOrderDTO();
bindingContext.Model = coDto;

My next step is extract the values from the request by reading the content of the request from the HttpActionContext object and storing it in a string. Then I find the start of my data by looking for the name of the first TextBox in the form (CustomerID) and splitting the following text wherever an ampersand appears–that will give me an array of name/value pairs (e.g. “CustomerID=ALFKI”):

string ct = actionContext.Request.Content.ReadAsStringAsync().Result;
ct = ct.Substring(ct.IndexOf("CustomerID"));
string[] vals = ct.Split('&');

I can now use LINQ statements to pull the name/value pairs that I want out of this array. Once I do that, I can extract the data that I want by looking for the equals sign that separates the name from the value. However, if the values contain “sensitive” characters (like forward slashes, spaces, or ampersands) those values will be URL encoded: A date like “1/15/1998 1:20:05 AM”, for instance, will turn up in the request’s content as the value “1%2F15%2F1998+1%3A20%3A05+AM.” I can use the WebUtility’s UrlDecode method to convert those encoded values back into their original characters.

So, to set the CustomerID property on my object, I use this code:

coDto.CustomerID = (from val in vals
                    where val.StartsWith("CustomerID")
                    select WebUtility.UrlDecode(val.Substring(val.IndexOf('=') + 1))).First();

Extracting the three GridView values is only slightly more difficult. One of the constants in the names of those TextBoxes is that they all begin with the name of the GridView they’re part of (GridView1 in my example). I use that to create another collection of just the name/value pairs belonging to the GridView:

var res = (from val in vals
           where val.StartsWith("GridView1")
           select val).ToList();

Then it’s just a matter of finding the value following the equals sign for each item in the collection, decoding the value,  doing a type conversion (for the dates), and putting the result in the appropriate property. Here’s the code for setting the OrderDate property the previous code will have put in the third position of the collection:

coDto.OrderDate = DateTime.Parse(WebUtility.UrlDecode(res[2].Substring(res[2].IndexOf('=') + 1)));

After moving all the values you can find into your object’s property, your method should return true to indicate successful processing.

Invoking the Model Binder

But there’s still a little work required to have the Web API use your custom model binder. First you need to create a factory object that will instantiate your model binder and return it. That’s just a class that inherits from ModelBinderProvider. Override its GetBinder method and, in the method, create your binder and return it:

public class CustomerOrderModelBinderProvider : ModelBinderProvider
{  
  public override IModelBinder GetBinder(System.Web.Http.HttpConfiguration configuration, Type modelType)
  {
   return new CustomerOrderModelBinder();
  }
}

The parameters passed to the GetBinder method allow you to create more complex logic here to choose among binders if you need to–but, again, I don’t need them for this example.

The last step is to tell the Web API when to use your factory. The most obvious way is to use the ModelBinder attribute on the parameter passed to my Post method. You just need to pass the attribute the type of your binder factory object (you’ll need a using statement for System.Web.Http.ModelBinding for this code to work). This mechanism assumes that I only want to use this model binder for this particular method:

public HttpResponseMessage Post([ModelBinder(typeof(CustomerOrderModelBinderProvider))]CustomerOrderDTO custOrderDTO)
{

You can also use the ModelBinder attribute on the DTO class itself if you want to use this custom model binder every time you use the class:

[ModelBinder(typeof(CustomerOrderModelBinderProvider))]
public class CustomerOrderDTO
{

This is a very bare bones, brute-force-and-ignorance model binder that doesn’t take advantage of much of the power built into the model binding framework. For instance, if I knew the names of my TextBoxes (something not possible with the GridView’s constantly changing names) I might have been able to use the GetValue method on the ValueProvider property of the ModelBindingContext to extract the values from the request; the HttpActionContext’s GetValidators method would allow me to execute any validation attributes applied to the properties on my object; if my conversions failed (or I couldn’t find any values), I should use the AddModelError method on the ModelState property of the HttpActionContext object to pass error messages to the service’s methods along with the DTO. However, all I wanted to demonstrate was that it’s possible to bind almost anything sent to your service to the resulting object: I figure if you can bind this WebForm, you can bind anything.

Peter Vogel

Processing Messages in a Self-Hosted Web API Service

In an earlier post, I showed how to host an ASP.NET Web API service on a server without IIS. In that post, I suggested that the most interesting object used in the self-hosting process is the HttpSelfHostConfiguration object–that’s the object that allows you to configure your service. In that last post, for instance, I used the HttpSelfHostConfiguration object to specify the service’s URL and routing rules. But that’s just a taste of the configuration object’s power: you can also use the HttpSelfHostConfiguration object to insert handlers into the Web API’s processing pipeline to centralize  pre- or post-processing on messages sent to and from your service (you can insert message handlers when hosting a Web API service in IIS, also).

You can add as many handlers as you want to the Web API processing pipeline: each handler’s output is automatically passed to the next handler in the pipeline. The handlers are processed in reverse order to the way that you add them to the pipeline (i.e. the handler you add first is the handler “closest” to your service and gets inbound messages after all the other handlers you add have processed the message; for the same reason, the first handler you add will see any outbound messages as soon as they leave the service and before any of the handlers you’ve added to the pipeline see the message).

As an example, let’s say that you don’t want the services your hosting to process any messages with the HTTP Delete verb because you don’t allow deletes: you simply mark records as deleted and stop returning those records to the client. All requests to delete records should, you’ve decided, be sent with the HTTP Put verb because they’re actually updates to the record’s Deleted field. You could, of course, simply not provide a Delete method in your service–that would generate a return error message of “The requested resource does not support http method ‘GET’.” should someone send your service a Delete request. However, you may want to send a response that’s more informative to any client using the Delete verb (alternatively, you might want to log these Delete requests). You could add a Delete method to each of your services that performed those actions but it would be a better practice to centralize that site-wide utility code in one place: a message handler.

Adding Handlers

The first step is to add your message handler to the configuration object’s Handlers collection before passing the configuration object to the host. This code assumes that the handler is called PHVHandler:

hcfg = new HttpSelfHostConfiguration("http://www.phvis.com");
PHVHandler hndlr = new PHVHandler();
hcfg.MessageHandlers.Add(hndlr);

If you want, you can limit a handler to processing only those requests for a single route. In that case, you pass the handler as the fifth parameter to the MapHttpRoute method (right after specifying any constraints on the route). This example adds a handler that will be used only for requests with “Customers” in the URL:

hcfg = new HttpSelfHostConfiguration("http://www.phvis.com");
PHVHandler hndlr = new PHVHandler();
hcfg.Routes.MapHttpRoute("HandledTemplate",
                         "Customers",
                         new { controller = "CustomerManagement" },
                         null,
                         hndlr);

Creating a Handler

A handler is a class that inherits from DelegatingHandler (you’ll need using statements for  System.Net and System.Net.Http for the following code to work). Once you’ve added the class you must override its SendAsync method. The SendAsync method is called automatically by the Web API for every request to your service. The method is passed an HttpRequestMessage that holds all the data related to the request to your service (and a CancellationToken, which I’ll ignore in this post):

class PHVHandler: DelegatingHandler
{
 protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
 {

If the PHVHandler is the last one added to the pipeline, it will get the HttpRequestMessage before any other handler has modified it; if other handlers were add to the configuration object after this handler, then the HttpRequestMessage will show the results of any modifications that handlers earlier in the pipeline have made. If you’re doing test driven development, by the way, you can test your handler by instantiating an HttpRequestMessage object, setting its properties, and passing it your method–something that’s virtually impossible to do with the ASP.NET HttpContext object.

Your message processing code goes in the SendAsync method. The following code checks to see if the Method (the HTTP verb) associated with this request is a Delete and, if so, stops the message from proceeding up the pipeline. To short-circuit processing and return a message to the client you need to create two objects: an HttpResponseMessage object, specifying a return value with some content (Forbidden and a string, , in this case) and a TaskCompletionSource (because these are asynchronous methods, Task-related objects are used to wrap most of the method’s inputs and outputs). With the two objects created, use the TaskCompletionSource object’s SetResult method to pass the HttpResponseMessage to the TaskCompletionSource. Once the TaskCompletionSource is configured, you can return it which is what this code does:

if (request.Method == HttpMethod.Delete)
{
  HttpResponseMessage rsp = new HttpResponseMessage(HttpStatusCode.Forbidden);
  rsp.Content =new StringContent("Deletes not accepted--use Put"); 
  TaskCompletionSource<HttpResponseMessage> tkc = new TaskCompletionSource<HttpResponseMessage>();
  tkc.SetResult(rsp);
  return tkc.Task;
}

However, if the message sent to your service isn’t using the Delete verb, it should be passed on to your service (or the next handler in the pipeline) for processing. To pass the message on up the pipeline, call the base version of the SendAsync method, passing the parameters you originally received in your version of the method:

return base.SendAsync(request, cancellationToken);

Calling the SendAsync method puts the message in the pipeline to go to the service. When your service finishes processing the message, the service will create a response message and send that back down through the pipeline. The object returned by the SendAsync method  in the previous code is the outbound response message created by the service (and, possibly, modified by any message handlers that the message has already passed through). You must return the result of the SendAsync method from your method to allow the message to continue through the pipeline back to the client. While it’s not obvious in this code, the SendAsync method is returning a Task object holding an HttpResponseMessage containing the service’s output message (again, the Task object is required to support asynchronous processing).

Altering the Inbound Message

However, a message handler can do more than just terminate processing. You can use a message handler to alter the message on its way up the pipeline. Rather than terminate processing when you see a Delete verb, for instance, you could change all Delete requests to Puts and let the messages continue on up the pipeline. As in the previous example, the following code first checks the inbound message to see if it’s a Delete. If it is, the code then alters the message before sending it on through the pipeline using the SendAsync method. The SendAsync method will (eventually, since its an asynchronous method) return the Task object holding the client’s HttpResponseMessage which you must return from your method:

if (request.Method == HttpMethod.Put)
{
 request.Method = HttpMethod.Put;
 return base.SendAsync(request, cancellationToken);
}

Altering the Outbound Message

Because the message passes through your handler on the way back to the client, you can also process the outbound message after it leaves the service and before it gets back to the client. This means waiting for your call to the base.SendAsync method to complete so that you can catch the outbound message–not a completely trivial task because SendAsync is an asynchronous method. If you’re working in .NET 4.0 then you’ll need to use the ContinueWith method to wait for the Task object returned from the SendAsync method. The ContinueWith method passes the Task returned from SendAsync to a lamba expression of your design. In that lambda expression you’ll typically want to extract the HttpResponseMessage from the Task and modify the message before letting the message continue through the pipeline. This example sets the StatusCode on the message to indicate that the request needs to be upgraded before returning the response (the Web API will take of wrapping the response in a Task):

return base.SendAsync(request, cancellationToken).ContinueWith((t) =>
{
  HttpResponseMessage rsp = t.Result;
  rsp.StatusCode = HttpStatusCode.UpgradeRequired;
  return rsp;
}

In .NET 4.5 you can take advantage of the await keyword which simplifies working with asynchronous methods–your code hardly looks asynchronous at all! First, you must add the async keyword to your method’s declaration:

class PHVHandler: DelegatingHandler
{
 async protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
 {

With the async keyword in place, you can use the await keyword to catch the output of the SendAsync method when it’s finally handed back to you. This example, as before, sets the StatusCode on the response message before returning the response:

HttpResponseMessage rsp = await base.SendAsync(request, cancellationToken);
rsp.StatusCode = HttpStatusCode.UpgradeRequired;
return rsp;

As you may have noticed, one of the nice features of self-hosting is that all your configuration code goes in one place: In the Windows Service that you’ll use to host your Web API service–which I find sort of convenient. I referred to Learning Tree’s course on creating .NET services (including the ASP.NET Web API) in my last post but I should also have mentioned Learning Tree’s course on deciding what services you need and how they should work together, Service-Oriented Architecture (SOA): A Comprehensive Hands-On Introduction (especially because I wrote the course).

Peter Vogel

Creating Your Own Host for a Web API Service

Kevin Rattan has done several posts on Microsoft’s ASP.NET Web API (you can find all of this blog’s Web API posts here) which have done a great job of showing (among other things) how the Web API is different from WCF. The Web API is designed from the ground up to leverage the HTTP protocol, for instance, which makes it easy to create RESTful services. But, like WCF, it’s ridiculously easy to add a Web API controller to either an ASP.NET or ASP.NET MVC application. And, also, like WCF you can create your own host for your Web API services.

Which, of course, raises the question: If it’s so easy to add a Web API service to a website why would you want to create your own host? Hosting your own Web API services is obviously a niche solution: most of the time you’ll want to leverage IIS as your service’s host. However, creating your own host allows you to control  your service in ways that might be difficult to implement if your service is part of a website hosted by IIS. For instance, with your own host the URL for your service is completely under your control (well, except for the server’s name) and isn’t constrained by the name of the website the service is part of. Managing your host is also independent of IIS management: You may want to self-host because you find that working with your Web Administrator is even less fun than working with your DBA–creating your own Web API host lets you bypass that person.

Configuring the Host Project

If you are going to create your own host, you should create the host as a Windows Service. That isn’t essential: practically any .NET project type can be used to host a Web API service. If you wanted your host to have a user interface that you could interact with then creating your host as a WPF or WinForms project would meet that goal more easily than a Windows Service project would. However, creating your host as a Windows Service is easy to do (as long as you don’t need the UI) and allows you to manage your host from the Services node in the Windows Management Console. For instance, by setting your Windows Service’s start mode as Automatic, your host will start up with the computer it’s running on and shut down with it.

The first step in creating your Web API host is to create a new Windows Service project in Visual Studio (File | New | Project | Windows | Windows Service).  Once the project is created, right mouse click on it in Solution Explorer and select Manage NuGet Packages to retrieve the Web API package  you need. Once in NuGet, search in the online section for “aspnet.webapi” to find all (and only) the Web API packages. From the packages listed, the one that you need so that you can create your own host is called Microsoft ASP.NET Web API Self Host (do not select Microsoft ASP.NET Web API Web Host). Click on the package, click the Install button, accept the licensing terms and you project is almost ready to write some code–there’s just two things left to do before you can start writing code.

First, add a reference to System.Web.Routing to your project–you’ll need this later to configure your service. You’ll also want your service to have a more meaningful name than the default Service1. Delete the default Service1 in your project, right-mouse click on your project in Solution Explorer, and select Add | New Item | General | Windows Service. Give your service a meaningful name (I used “PHVService”) and click the Add button. Now you’re ready to write code.

Writing the Windows Service

A Windows Service initially displays the Service’s graphical designer which you can ignore–open its code file by double clicking on the designer. There are two key events in a Windows Service’s life: when it starts and when it stops. The methods associated with these events (OnStart and OnStop) are, typically, where you’ll want to load your host and where you’ll want to shut your host down. I’m going to create my host in the OnStart event and shut it down in the OnStep event (for the following code to work, you’ll need to add using statements for System.Web.Http.SelfHost and System.Web.Http to Service’s code file). Since that means that my HttpSelfHostServer must be available in both methods, I declare it at the class level:

 partial class PHVService : ServiceBase
{
  private HttpSelfHostServer shs;

First, create an HttpSelfHostConfiguration object that will specify how your service behaves. When you instantiate the HttpSelfHostConfiguration object pass it the endpoint for your service (the initial part of the endpoint will have to be the name of the computer that your service is running on–the rest is up to you):

 protected override void OnStart(string[] args)
{
  HttpSelfHostConfiguration hcfg =
    new HttpSelfHostConfiguration("http://phvis.com/MyServices");

The configuration object gives you the ability to configure a great many things about your service–all but one of which is optional. You must set up a route to the controller that makes up your service. This example sets up the simplest possible route (“http://phvis.com/MyServices/Customers&#8221;) and ties it to a controller called CustomerManagementController:

hcfg.Routes.MapHttpRoute("CustomerServiceRoute",
                         "Customers",
                         new { controller = "CustomerManagement" });

Finally, you’ll want to open your host. Create your HttpSelfHostServer, passing your configuration object,and then call the host’s OpenAsync method:

shs = new HttpSelfHostServer(hcfg);
shs.OpenAsync();

The OnStop method is simpler. When the service is shut down (as part of the server shutting down, for instance) this method will be called automatically. In the OnStop method, you want to call the HttpSelfHostServer object’s CloseAsync method to start shutting down your host. However, I don’t think it would be a good practice to let the service continue to the end of its OnStop method until your host really has shut down. So, in this code, I’ve used the Await method to hold execution until the CloseAysnc method completes (I also call the host’s Dispose method just to free up any remaining resources that the host might be controlling):

protected override void OnStop()
{
  shs.CloseAsync().Wait();
  shs.Dispose();
}

There’s still stuff to do. It’s still your responsibility to create the Web API controller referenced in the route you created. You should also create a setup project you can use to install your Windows Service on its server. And, of course, while I’ve shown you how to create your own host, I haven’t shown you how you can configure your Web API service. That’s another post.

Learning Tree has an excellent course about creating services in .NET that covers the ASP.NET Web API: WCF and Web API .NET Services: A Comprehensive Hands-On Introduction.

Peter Vogel

Dependency Injection with Ninject and MVC 4

This week I uploaded a new version of www.cocktailsrus.com. I didn’t change all that much… just upgraded the server to .NET 4.5, upgraded MVC4 from beta to release, Entity Framework to 5.0, jQuery to 1.8.3, jQuery UI to 1.9.2 and jQuery Mobile to 1.2.0. Oh, and I finally made the move to storing the images on Amazon S3 (and, of course, I wrote a program to upload all the existing images ready for the new version).

So, not much change at all, then 🙂

I’ve been itching to make this change for a long time, but now that I’ve done it I have a potential problem: the production and development versions are using different data store types for images. I want to make sure that if I’m in debug mode I call the local file storage version of my PhotoRepository, and if I’m in release mode (and hence on the live server) I am using Amazon S3. There are all sorts of primitive ways I could manage this. I could, for example, change the using directive when I switch versions, going from cocktails.storage to cocktails.storage.amz. But all such approaches are fiddly and prone to human error. What I really want is an automated solution that picks the right object automatically without my intervention.

It’s time for dependency injection!

There are a number of DI frameworks available for .NET, but I decided to go with Ninject (since it looked a. reasonably simple and, b. sufficient for my purposes). Here is my design goal:

The application should automatically select the correct PhotoRepository depending upon whether it is in debug or release mode.

This is what I did to achieve it:

  1. Use NuGet to install the base Ninject framework and the MVC extensions into the MVC project

Don’t worry that it says MVC3 – it works in MVC 4 as well.

This will add a NinjectWebCommon file to App_Start. You could use this, but I did all my work inside Global.asax instead, so I excluded NinjectWebCommon from the project.

  1. Inherit Global.asax from NinjectHttpApplication instead of just HttpApplication and implement protected override Ninject.IKernel CreateKernel() and the override of OnApplicationStarted (which you might have to add yourself).
  2. Move all the code setting up routes etc. from the Application_Start routine to OnApplicationStarted and then remove Application_Start
  3. We’re now ready to start programming. Move to CreateKernal() and create a standard kernel. Then load the executing assembly.

  1. At this point, all the plumbing is in place – we can start setting up our dependencies. What I really want to do is set a dependency on the business/service layer – but for that I first need to create the dependency from the controller to the Service layer. So let’s add a mapping between IBeverageService and the BeverageService implementation:

Except, of course, I don’t actually have an IBeverageService interface because I haven’t needed one before now.

  1. So before I do anything else I have to refactor and create the appropriate interface

.

  1. Not only does that work, I can get Visual Studio to do all the heavy lifting for me. So I go right on and create interfaces for all of my Service classes.
  2. Now that I have interfaces, Ninject will look for the constructor with the most arguments in the specified implementation and use it to create the objects. So now I need to add constructors to all of my service methods so that Ninject can pass in the concrete implementations at runtime. I can then assign them to private read only variables. Like this:

  1. So now I need to tell Ninject which PhotoRepository implementation to use, and since I want different ones between development and production, our old friend conditional compilation can be really helpful here:

  1. Great. We can now pass through the appropriate PhotoRepository implementation to BeverageService. But first we have to add an appropriate constructor to our controller so that BeverageService itself is injected appropriately:

  1. And that’s it. Now when the application runs, Ninject is injecting the types specified inside my Gobal.asax – and giving me the appropriate image storage implementation. Here is the complete code for the CreateKernel() method with all the Service implementations assigned to the appropriate interfaces.

What do I like about this? The fact that my service layer does not even have to have a reference to either storage .dll, and that my application automatically switches to the appropriate back-end depending on the context.

What do I dislike about this? The fact that my UI, which previously only knew about the Service layer and was completely ignorant of the rest of the system now needs to have references to all the objects I might potentially inject. Is it a price worth paying? Definitely.

Kevin Rattan

For other related information, check out this course from Learning Tree:

Building Web Applications with ASP.NET MVC

Web Forms Data Annotation Validation – Part 3

This is the third part in my look at Data Annotation validation in Web Forms in the Visual Studio 2012 Release Candidate. In the first part, I showed the server-side support for Data Annotation validation and model binding. In the second, I proposed one approach to providing client-side validation using jQuery plugins and a custom validator control that injects validation rules into the input element’s class attribute. The problem with that approach was an external dependency on the metadata plugin and the need to inject JavaScript into the page. So I got to thinking about how I might piggy-back on the unobtrusive validation support to produce a custom validator that worked in exactly the same way as the existing validators, but where the rules and messages were all derived from Data Annotations.

So the first thing to do was see how the existing validators work. I added various validators to a sample form and took a look at the underlying HTML. This is what I found:

client side unobtrusive attributes

There’s lots of interesting stuff here. The Text becomes the content of the span; the ErrorMessage is in data-val-errormessage; the validation method is in data-val-evaluation function; etc. If I can get my validator to read the Data Annotations and output the appropriate spans, that should give me the client-side validation I want.

I began in the same way as last time, by creating a new ASP.NET Web Control library and inheriting from the base validator. That code is in the previous posting, so I’m not going to repeat it here. (If you want to see the full code, I’ll put a link at the bottom of this post).

The reflection code is also the same, but one thing that is different is that this time I need to render HTML directly from the control, so I have to override the render method:

render method

The first thing I need is template for my span(s). I am going to put in {0} placeholders for the bits that need to change, and reuse the same basic string every time. Here is my template:

private static string template = “<span id=\”{0}\” data-val-evaluationfunction=\”{1}\” data-val=\”true\” data-val-errormessage=\”{2}\” data-val-controltovalidate=\”{3}\” {4} {5}>{6}</span>”;

Now, as I loop through the Data Annotations I can use string.Format() to fill in the blanks (note the += on the local spanString variable: that means I can add more spans if there are multiple annotations).

building the string

The arguments to the method are as follows:

  • this.ClientID is my current validator’s Id.
  • vat.ErrorMessage is the ErrorMessage from the Data Annotation.
  • c.ClientID is the control I am validating.
  • The string literals set up the validation for a required field
  • So where do display and message come from?

Display maps to the typical Validator display choices – static, dynamic and none. It’s initialized as style=”display: none;” data-val-display=”None” and overridden as appropriate. The message is the ErrorMessage to display in the control – as potentially overridden by the Text attribute.

message and display variables

So let’s add a reference inside our test web project and then add the new DataAnnotationValidator to the toolbox. Then we need to add a Required attribute to the Email class. (I added “DA” at the end of the message to confirm where the message was coming from).

required attribute

Then we need to set up the properties on our DataAnnotationValidator:

DataAnnotationValidator in aspx source

Now we can test it… and see that it works! We are now running client-side validation from Data Annotations, and it works and displays in exactly the same way as the other validators. And we have no additional dependencies and JavaScript injected into the page. Hurray.

working validation

Of course, we want to be able to validate other attributes as well. I went ahead and implemented several of them using the underlying RegularExpressionValidator. First I created a method to build all the regular expression spans:

regular expression builder

Then I called it from the various case statements for validation attributes:

switching attributes

Not forgetting the easiest one of all: the RegularExpressionAttribute itself:

RegularExpressionAttribute

Now I could play around with different values and messages in my Model….

Data Annotations

….and see my working Web Forms client-side Data Attribute validation:

validation working

I’ll probably refactor for robustness at some point, as well as adding support for additional attributes, but if you’re interested in the code for this version of the DataAnnotation validator, it’s online here: DataAnnotation2.txt.

Kevin Rattan

For other related information, check out these courses from Learning Tree:

Building Web Applications with ASP.NET and Ajax

Web Forms Data Annotation Validation – Part 2

In my last post I reviewed the new Web Forms support for server-side validation using Data Annotations, and ended with my frustration at not being able to find out how (or if) Microsoft had implemented the matching client-side validation. I promised to look at two different implementations that would provide client-side validation. This post is an overview of my first pass at a solution–using the jQuery validation plugin.

My hope was that since Microsoft had implemented client-side validation in MVC, all I would have to do was rip the code out of an MVC template and tweak it a bit to make it work in Web Forms. Sadly, it wasn’t going to be as easy as that. I brought over the appropriate JavaScript files, tried adding the web.config settings, but nothing happened. Still, at least I had the MVC JavaScript files and that meant I had the jquery.validate plugin – and since I’ve used that to get around issues in MVC validation, I could do so again for Web Forms. All I had to do was read the Data Annotations in a custom validator and inject the appropriate rules into the control to be validated. So… here goes:

The first thing I did was create a new ASP.NET server control so that the validator would be just another control in my toolbox:

New project dialog

Then I added a new class and inherited from the base validator:

inheriting base validator

That meant implementing the single method EvaluateIsValid():

overriding EvaluateIsValid

I simply return true here because the validator isn’t actually going to do any validation–it’s just going to inject the rules into the form element so that the validate plugin can do that for me. The validate plugin is able to read validation rules out of HTML class attributes. I’m going to translate DataAnnotations into the object literal arguments the plugin expects, so that when the validator reads the following Data Annotation…

Data Annotations

….it generates “{required:true, messages:{‘The from address is required’}}“inside the class attribute:

generated html

(In order for this to work, I’ll have to add the metadata plugin to my master page, as well as the validate and validate.unobtrusive plugins that I “borrowed” from the MVC template).

I’m not going to render this control itself, just inject content into the control it’s validating, so I override the PreRender event. I do the work inside the event handler (and inside a check to see if IsPostBack is false so that I’m only inject my code once). I even commented out the call to base.OnPreRender. Why bother? I’m not going to render it.

onprerender

The first task is to read the Data Annotations, so I need a reference to System.ComponentModel.DataAnnotations. Now I can use reflection to read the annotations, thus:

reflection

As you can see, I’m using TypeName, TypeAssembly and TypeProperty properties on my class to provide all the information I need to get hold of the object and its Data Annotations. These need to be provided by the UI developer, thus:

DataAnnotationValidator in aspx source

Now it’s just a question of checking the type of the validation attribute and creating the appropriate string. I did this by building two collections–one of rules, the other of messages. Here are the collections and a method used to populate them:

properties

And here is a switch inside the loop through the attributes that calls the AddValidation() method:

switching attributes

Once I have set up the rules and messages, all I need to do is create the literal and inject it into the control.

building the string

Then it’s time to test it… and nothing happens. That’s because although the validate plugin is there, there’s no call to .validate() on the page. So now I need to add in a scriptlet to make the plugin runs:

scriptlet

And then I need to register that script on the page.

registering script

Phew! Finally we’re done. All I have to do is add a reference to the library, add the DataAnnotationValidator to the toolbox (right-click and choose items, then browse to the library) and then add the appropriate validators to the page and give them the right property settings:

property settings

The DataAnnotation validator translates the rules into a form understood by the validate plugin, the validation runs and we have client-side validation:

working validation

Obviously, there are a lot of things that can be improved in this version. It doesn’t cover all the possible Data Annotations. It doesn’t allow for missing error messages. It only validates TextBox controls. I could improve it, but I’m not going to: I decided I didn’t like the dependency on the metadata plugin, and I hated having to inject JavaScript into the page. So I decided to go back to square one, forget about bringing in any scripts from the MVC version and work with the unobtrusive validators that come with the Web Forms template instead. And that’s what I’m going to cover in my next post.

(If you’re interested in the full code for this version of the DataAnnotation validator, it’s online here: DataAnnotation.txt.)

Kevin Rattan

For related information, check out these courses from Learning Tree:

Building Web Applications with ASP.NET and Ajax

jQuery: A Comprehensive Hands-On Introduction

Web Forms Data Annotation Validation – Part 1

This will be the first of three posts on Data Annotation validation in Web Forms in Visual Studio 2012. In the first one, I’ll talk about what I like (and what I don’t) in the new release, and in the following two I’ll show two alternative solutions to dealing with the frustration I’ve started to feel over what is either a missing feature or very-hard-to-find documentation.

First off: I love Data Annotation validation. I’ve mentioned it in a number of posts and I really like being able to annotate my classes so that the validation rules travel around with the class. I always hoped and expected that Microsoft would provide Data Annotation validation in the new release of Web Forms, given that it’s already in WPF, Silverlight and MVC. I was also hoping that Microsoft would give us unobtrusive client-side validation.

The Good News: they have.

The Bad News: they don’t seem to have done both together.

(Or at least, if they have, I can’t find any documentation on it. There are LOTS of articles out there talking about the new Data Annotation validation and also about the new unobtrusive client-side validation–but when they refer to Data Annotation validation, they are talking about server side validation, and when they talk about unobtrusive validation they’re talking about the existing property-based validators. I’ll be delighted (and grateful) if anyone out there can point me at any documentation that shows Microsoft has implemented client side Data Annotation validation in Web Forms as they did in MVC–in which case my own experiments in that direction, to be detailed over the next two posts, will have been merely a fun coding excursion and not actually necessary).

So, back to the good news.

I was playing with the new model binding functionality in Web Forms, and it’s really nice. I created an Email model which had the necessary data, a static method to return an empty Email object for the model binder and the code to send the email, thus:

Email Model class

Then I bound a Form View to my model and got rid of everything except the Insert View, thus:

FormView bound to Email model

This allows me to put the following method in the code behind and pass all the work to the business object:

code behind method

That works beautifully, and with MVC-like levels of Separation of Concerns goodness. Now if I just add some Data Annotations…

Data Annotations

I should have validation, too. And I do. But sadly, only on the server side. The page does a full round trip before showing the error messages.

server side validation

So I looked all over to see how I could turn on client side validation… and just couldn’t find it. In the end, I decided it was going to take me less time to write my own version than to find Microsoft’s implementation (if any). So I did so… twice. And in the next couple of posts I’ll look at two different ways of providing client-side Web Form validation using Data Annotations.

Kevin Rattan

For related course information, check out Learning Tree’s course, Building Web Applications with ASP.NET and Ajax.

Working with SSL at Design Time with IIS Express

One issue that arose from my planned switch to serving images from Amazon S3 was: how to deal with HTTPS?

Hitherto, that’s been a non-issue. I used a relative path for images so the switch between HTTP and HTTPS happened automatically and painlessly. Now, of course, there is a potential problem. I have to use fully qualified paths for the images – and if an HTTPS page tries to serve images over HTTP, the browser will give the end user a warning about mixed content. So what to do?

The solution, of course, is to switch the images over to HTTPS along with the rest of the page. S3 supports HTTPS, so that’s fine – but there are still a couple of questions:

  1. How to manage switching over to HTTPS?
  2. How to test it in the development environment?

I’ll deal with the second one first. One of the nice things about Visual Studio 2012 is that it comes with IIS Express as the development server. That means you can use and test HTTPS/SSL during development. All you have to do is select the website in Solution Explorer and then change the property setting to enable SSL.

properties window

That’s it. Now, if you browse to the alternative URL you have HTTPS. You’ll get a warning message because there’s no certificate, but the functionality is all there.

So now we can write code to switch to HTTPS for images and test whether it actually worked.

I decided the easiest thing to do was have two configuration settings – one for standard images and one for HTTPS images. Here is the main configuration for the development setup (I left HTTP as relative, and just switched to a full path for HTTPS):

configuration

And here is the configuration transform for deployment to the live setup:

configuration transform

Now the question is – where to pick this up? In the current/old version, I set a ViewBag variable inside the base controller’s constructor. I can’t do that now because I need to find out whether the request uses HTTPS… and the context is not available inside the constructor. So it’s back to the drawing board. I don’t want to have to repeat the code, and I can’t use inheritance to get what I want… so it’s time for attribute based programming – in this case, with an action  filter. As the View is about to execute I check if the Request is over HTTPS, and switch the path appropriately.

Code sample OnResultExecuting

I’m checking that this is a ViewResult, so I can safely add this as a global filter without have to worry about methods that don’t return views:

Code sample register global filters

So now when I switch over to HTTPS, my path switches appropriately, and I don’t get annoying messages about delivering mixed content:

working ssl

Kevin Rattan

For other related information, check out this course from Learning Tree:

Building Web Applications with ASP.NET MVC

Building Web Applications with ASP.NET and Ajax


Learning Tree International

.NET & Visual Studio Courses

Learning Tree offers over 210 IT training and Management courses, including a full curriculum of .NET training courses.

Free White Papers

Questions on current IT or Management topics? Access our Complete Online Resource Library of over 65 White Papers, Articles and Podcasts

Enter your email address to subscribe to this blog and receive notifications of new posts by e-mail.

Join 29 other followers

Follow Learning Tree on Twitter

Archives

Do you need a customized .NET training solution delivered at your facility?

Last year Learning Tree held nearly 2,500 on-site training events worldwide. To find out more about hosting one at your location, click here for a free consultation.
Live, online training

%d bloggers like this: