Creating the WCF client code class from a WCF host.

A WCF consumer (client) needs to have some references to the types in the WCF host. If you are building everything on a single computer and testing, you can simply have your client project refer to the host project and then it can see the types, and can create a Binding as follows:

 

static void InitSomeService()
{
string hostAddress = System.Configuration.ConfigurationManager.AppSettings[“SomeHostUriHttp”];
EndpointAddress address = new EndpointAddress(new Uri(hostAddress));
BasicHttpBinding binding = new BasicHttpBinding();
ChannelFactory<ISomeService> factory = new ChannelFactory<ISomeService>(binding, address);
solService = factory.CreateChannel();
}

 

When you deploy this to a remote server this won’t really work because you don’t deploy the host dlls with the client, and if you were developing a client to talk to a 3rd party WCF service then you wouldn’t have the host files to deploy anyway.

So you need to create copies (or atleast representations ) of the original ISomeService interface and all the other datacontracts. You do this with the svcutil too inlcuded with Visual Studio. The easiest way is to fire up the host and run it. Then open the VS command line and type:

svcutil http://localhost:8000/yourservice

 

It will output the needed files into the same folder as svcutil, and tell you where they are. Now include those cs file in your project, and remove the references to the HOST project if you were referencing the HOST project previously.

Returning HttpResponseMessages from the ASP.Net webAPI

For consistency, I’ve adopted the following return codes, but I may alter these if there is some compelling reason or someone sheds some light on why these might not be the best options:

HTTPGet = Select (Success -> return the items, but don’t return a return message)
(Fail -> throw new HttpResponseException(HttpStatusCode.NotFound = 404 );)

HttpPost = Insert ( Success -> return HttpStatusCode.Created = 201)
( or Assumed Success -> HttpStatusCode.Accepted = 202 )

( Fail -> return HttpStatusCode.ExpectationFailed = 417)

HttpPut = Update ( Success -> HttpStatusCode.OK = 200)
( or Assumed Success -> HttpStatusCode.Accepted = 202 )

( Fail -> return HttpStatusCode.ExpectationFailed = 417)

HttpDelete ( Success -> HttpStatusCode.NoContent = 204)
( or Assumed Success -> HttpStatusCode.Accepted = 202 )

( HttpStatusCode.ExpectationFailed = 417)

HttpPatch ( Success -> HttpStatusCode.OK = 200)
( or Assumed Success -> HttpStatusCode.Accepted = 202 )

( Fail -> return HttpStatusCode.ExpectationFailed = 417)

Also, for HttpGets, I’m not returning the entire entity back, mainly because in my case I’m dealing with RPC type setup and I don’t have the full entity, but I’m often calling functions like ‘int CreateEntity()’ which will create an entity and simply return an id, so what I’m doing is putting the return value into the content of the HttpResponseMessage. The following function is an example:

[HttpPost]
public HttpResponseMessage CreateAnObject(string name )
{
int retVal = _equipService.CreateAnObject(name);
if (retVal > 0)
{
//succeeded
return ControllerContext.Request.CreateResponse<int>(HttpStatusCode.Created,retVal);
}
else
{
//failed
return ControllerContext.Request.CreateResponse(HttpStatusCode.ExpectationFailed);
}
}

Setting up RPC Routing for WebAPI

The MVC4 webAPI has a default routing for CRUD operations where it is setup well to work with each controller having limited functions, so Actions are not passed to the controller. I needed to setup RPC style webAPI project that could have many calls to a single controller and then differentiate which action to take based on the specified action specified in the url. After a lot of headaches, I found that you can edit the App_Start/webAPIConfig.cs file from:

 

public static void Register(HttpConfiguration config)
{

      config.Routes.MapHttpRoute(
       name: “DefaultApi”,
       routeTemplate: “api/{controller}/{id}”,
        defaults: new { id = RouteParameter.Optional }
        );
// Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable<T> return type.

// To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries.
// For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712.
//config.EnableQuerySupport();

// To disable tracing in your application, please comment out or remove the following line of code
// For more information, refer to: http://www.asp.net/web-api
config.EnableSystemDiagnosticsTracing();
}

 

to:

 

public static void Register(HttpConfiguration config)
{

           config.Routes.MapHttpRoute(
           name: “RestPCApi”,
           routeTemplate: “{controller}/{action}”,
           defaults: new { action = RouteParameter.Optional }
            );

           config.Routes.MapHttpRoute(
           name: “DefaultApi”,
           routeTemplate: “{controller}/{action}/{id}”, // URL with parameters
           defaults: new { controller = “api”, RouteParameter.Optional } // Parameter defaults
           );

// Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable<T> return type.
// To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries.
// For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712.
//config.EnableQuerySupport();

// To disable tracing in your application, please comment out or remove the following line of code
// For more information, refer to: http://www.asp.net/web-api
config.EnableSystemDiagnosticsTracing();
}

Setting up Ninject DI on MVC4 WebAPI application

Thanks to http://www.peterprovost.org/blog/2012/06/19/adding-ninject-to-web-api, this setup is pretty easy.

Create your MVC4 WebAPI project.

Use Nuget to install Ninject.Web.Common (NOT Ninject MVC3). This will setup the NinjectWebCommon.cs file in the App_Start folder.

Add the following code in your App_Start folder:

 

using System;
using System.Web.Http.Dependencies;
using Ninject;
using Ninject.Syntax;

namespace CHR.WebAPI.App_Start
{

// Got this from http://www.peterprovost.org/blog/2012/06/19/adding-ninject-to-web-api
// Provides a Ninject implementation of IDependencyScope
// which resolves services using the Ninject container.
public class NinjectDependencyScope : IDependencyScope
{
IResolutionRoot resolver;

public NinjectDependencyScope(IResolutionRoot resolver)
{
this.resolver = resolver;
}

public object GetService(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException(“this”, “This scope has been disposed”);

return resolver.TryGet(serviceType);
}

public System.Collections.Generic.IEnumerable<object> GetServices(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException(“this”, “This scope has been disposed”);

return resolver.GetAll(serviceType);
}

public void Dispose()
{
IDisposable disposable = resolver as IDisposable;
if (disposable != null)
disposable.Dispose();

resolver = null;
}
}

// This class is the resolver, but it is also the global scope
// so we derive from NinjectScope.
public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
{
IKernel kernel;

public NinjectDependencyResolver(IKernel kernel)
: base(kernel)
{
this.kernel = kernel;
}

public IDependencyScope BeginScope()
{
return new NinjectDependencyScope(kernel.BeginBlock());
}
}

}


Modify CreateKernel in NinjectWebCommon.cs as follows:

private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

RegisterServices(kernel);

// added per http://www.peterprovost.org/blog/2012/06/19/adding-ninject-to-web-api
// Install our Ninject-based IDependencyResolver into the Web API config
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
return kernel;
}

Configure your bindings as follows (in NinjectWebCommon.cs) :

private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IProductRespository>().To<ProductRepository>();

}

Works great!

MVC4 SPA projects stuck on splash screen

I was trying to run the MVC4 SPA startup kits and they would hang on the splash screen. This was occurring when running from debug mode in Visual Studio 2012.  I was finally able to determine the issue was related to a timeout issue when Durandal was loading the require.js scripts.

 

This issue occurred on my work computer, for both the Durandal Starter kit and the Hot Towel Starter kit, which both rely on require.js. I didn’t try the other kits.

I found that my work machine was setup to use IISExpress as the default server for debugging and my home computer was set to use the Visual Studio built-in server for debugging. I switched my work computer to use the built-in Visual Studio server and had no more issues. I assume this is an issue with relative urls not working properly in IISExpress, but I didn’t keep digging into to it so not sure if that is truly the case. 

 

To switch to use the built-in server, right click your website project in Solution Explorer, click Properties, then on the ‘Web’ tab of the properties page, select ‘Use Visual Studio Development Server’.