Friday, November 28, 2014

ASP.Net: Web API 2 + Help Pages + OData

Doing each of them separately is fairly easy and there's lots of tutorials on how to do it. But as for mixing them together, I've not seen much. Some blogs claim it's not possible and buggy and mostly lead to 404 and 406 errors. Well, out of luck, I made it work. The secret is in the ROUTING!

I don't understand all the concepts behind this and I believe most of us don't, and don't care to. Still, feel free to explain the unexplained in the comments.

So, I started with a ASP.Net Application project. I Selected Web API for the template so I could have the help pages ready. Then I added the needed stuff for OData V4 following this really nice tutorial. Last, I had to configure the ROUTES, and that is where all hell resides (well, that's what all the blog posts and obscure SO questions lead me to think). THe following has been taken from my SO answer.

The order in which the routes are configured has an impact. In my case, I also have some standard MVC controllers and help pages.

Global.asax:
protected void Application_Start()
{
 AreaRegistration.RegisterAllAreas();
 GlobalConfiguration.Configure(config =>
 {
  ODataConfig.Register(config); //this has to be before WebApi
  WebApiConfig.Register(config);
 });
 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
 RouteConfig.RegisterRoutes(RouteTable.Routes);
}

The filter and routeTable parts weren't there when I started my project and are needed.

ODataConfig.cs:
public static void Register(HttpConfiguration config)
{
  config.MapHttpAttributeRoutes(); //This has to be called before the following OData mapping, so also before WebApi mapping
    
  ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
    
  builder.EntitySet("Sites");
  //Moar!
    
  config.MapODataServiceRoute("ODataRoute", "api", builder.GetEdmModel());
}

WebApiConfig.cs:
public static void Register(HttpConfiguration config)
{
  config.Routes.MapHttpRoute( //MapHTTPRoute for controllers inheriting ApiController
     name: "DefaultApi",
     routeTemplate: "api/{controller}/{id}",
     defaults: new { id = RouteParameter.Optional }
  );
}

RouteConfig.cs:
public static void RegisterRoutes(RouteCollection routes)
{
  routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
  routes.MapRoute( //MapRoute for controllers inheriting from standard Controller
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
  );
}

This has to be in that EXACT ORDER. I tried moving the calls around and ended up with either MVC, Api or Odata broken with 404 or 406 errors.

So I can call:

localhost:xxx/ -> leads to help pages (home controller, index page)

localhost:xxx/api/ -> leads to the OData $metadata

localhost:xxx/api/Sites -> leads to the Get method of my SitesController inheriting from ODataController

localhost:xxx/api/Test -> leads to the Get method of my TestController inheriting from ApiController.

Saturday, November 22, 2014

Linux: Slow wifi with Intel and iwl3945

I have this lovely Thinkpad T60 on which I replaced the Atheros Wifi card for an Intel one a few years ago. I'm using Fedora 20 on it and noticed the wifi connection, although negociated to 54Mbps wouldn't get any better actual speed than 1 Mbps. I was on the edge of getting an Atheros back but here's what I did to fix the problem:

As root, add a new file:
/etc/modprobe.d/iwl3945.conf
With content:
options iwl3945 disable_hw_scan=0
then:
modprobe -r iwl3945 
modprobe iwl3945
No need to restart, the changes were instantaneous.

I don't know if it also helped, but prior to that I had removed NetworkManager and installed wicd instead. Look around on how to do this if the above solution alone didn't work. One thing though if you install wicd-gtk, I had to add my user to the "users" group and then reboot. This had nothing to do with the problem. I reinstalled NetworkManager and everything was still fine.

All thanks to this comment on ubuntu launchpad. It's from 2011 but still works.

Monday, November 17, 2014

WatchGuard: failed to open shared memory for openvpn command

I was having problem connecting to a VPN using WatchGuard Mobile VPN with SSL. Here's my log:
2014-11-17T10:16:27.568 VERSION file is 5.23, client version is 5.23
2014-11-17T10:16:27.851 failed to open shared memory for openvpn command (error: 2), please check the WatchGuard SSLVPN Service
2014-11-17T10:16:27.851 Failed to launched openvpn. retCP=0
I tried various things, and it turns out that I was using version 11.9.1. I uninstalled the client and reinstalled the version located on the firewall, which was 11.7.3 and now everything works.

Along the hair pulling and googling, the typo in the last log line made me laugh a bit.