title: How do I do RPC style Asp.Net Web API calls properly?
body: <p><strong>UPDATE 9/12/2012:</strong></p>
  
  <p>I shared my code with a co-worker and everything worked fine for him the first time without any changes.  So, there must be something environmental on my box,  Anyone have any thoughts?</p>
  
  <p><strong>See Update Below</strong></p>
  
  <p>Set Up:</p>
  
  <p>.Net 4.5</p>
  
  <p>Self Hosted (console app) .Net 4.5 Web API application</p>
  
  <p>Test harness using MSTest</p>
  
  <p>My Web API app is mostly full of REST ApiControllers which all work properly as I expect with standard CRUD type stuff.  Now I have a requirement (to add some objects to an internal queue) which doesn't seem to fit well into the REST CRUD model.  I found <a href="http://encosia.com/rest-vs-rpc-in-asp-net-web-api-who-cares-it-does-both/" rel="nofollow">this</a> article which seems to say that you can do RPC style non-REST operations in Web API just fine.</p>
  
  <p>I've written a new controller which looks like this:</p>
  
  <pre><code>public class TaskInstanceQueueController : ApiController
  {
      public void Queue(TaskInstance taskInstance)
      {
          // Do something with my taskInstance
          Console.WriteLine("Method entered!");
      }
  }
  </code></pre>
  
  <p>In my proxy class which calls this, I have code which looks like this:</p>
  
  <pre><code>public class TaskInstanceQueueProxy : ITaskInstanceQueueProxy
  {
      readonly HttpClient _client = new HttpClient();
  
      public TaskInstanceQueueProxy()
      {
          var apiBaseUrl = System.Configuration.ConfigurationManager.AppSettings["APIBaseUrl"];
          _client.BaseAddress = new Uri(apiBaseUrl);
          _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
      }
  
      public void QueueTaskInstances(TaskInstance taskInstance)
      {
          QueueTaskInstanceViaAPI(taskInstance);
      }
  
      private async void QueueTaskInstanceViaAPI(TaskInstance taskInstance)
      {
  
          var response = await _client.PostAsJsonAsync("api/TaskInstanceQueue/Queue", taskInstance);
          var msg = response.EnsureSuccessStatusCode();
      }
  
  }
  </code></pre>
  
  <p>Here are my routes:</p>
  
  <pre><code>    config.Routes.MapHttpRoute("API Default", "api/{controller}/{id}", new {id = RouteParameter.Optional});
      config.Routes.MapHttpRoute("API RPC Style", "api/{controller}/{action}", new { id = RouteParameter.Optional });
  </code></pre>
  
  <p>When I run a test against my proxy, I don't get any errors, but no break point ever hits inside my controller method, nor does the Method entered! message appear in the console.  The break line on the var msg line never hits either.  For whatever reason, it doesn't look like I'm properly using the HttpClient object to do this.  </p>
  
  <p>Again, this web api app is working just fine with a bunch of other apicontrollers, but they're all doing standard REST stuff.</p>
  
  <p>Anyone have any clues?</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>If I put a try/catch around the PostAsJsonAsync call, I get the following:</p>
  
  <pre><code>A first chance exception of type 'System.Threading.ThreadAbortException' occurred in mscorlib.dll
  System.Threading.ThreadAbortException: Thread was being aborted.
     at System.Threading.Tasks.TaskHelpers.RunSynchronously(Action action, CancellationToken token)
     at System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext)
     at System.Net.Http.ObjectContent.SerializeToStreamAsync(Stream stream, TransportContext context)
     at System.Net.Http.HttpContent.LoadIntoBufferAsync(Int64 maxBufferSize)
     at System.Net.Http.HttpClientHandler.PrepareAndStartContentUpload(RequestState state)
  --- End of stack trace from previous location where exception was thrown ---
     at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
     at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
     at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
     at TaskManagerProxy.TaskInstanceQueueProxy.&lt;QueueTaskInstanceViaAPI&gt;d__0.MoveNext() in c:\Moso\MOSO\MOSO.Infrastructure\tm\TaskManagerProxy\TaskManagerProxy\TaskInstanceQueueProxy.cs:line 30
  </code></pre>
  
  <p>Line 30 is the line with the call.</p>