title: Model-bind interface property with Web API
body: <p>I have a command looking like:</p>
  
  <pre><code>public interface ICommand {
      // Just a marker interface
  }
  
  public interface IUserAware {
      Guid UserId { get; set; }
  }
  
  public class CreateSomething : ICommand, IUserAware
  {
      public string Title { get; set; }
  
      public Guid UserId { get; set; }
  }
  </code></pre>
  
  <p>The REST request is:</p>
  
  <pre><code>PUT /create HTTP/1.1
  UserId: 7da6f9ee-2bfc-70b1-f93c-10c950c8f6b0 // Possible an Auth token and not a userId like here.
  Host: localhost:63079
  Content-Type: application/json
  Cache-Control: no-cache
  {
      "title": "This is a test title"
  }
  </code></pre>
  
  <p>I have a API controller action looking:</p>
  
  <pre><code>[HttpPut, Route("create")]
  public IHttpActionResult CreateSomething([FromBody]CreateSomething command)
  {
      // I would like command.UserId already binded here
  }
  </code></pre>
  
  <p>The <code>Title</code> property on my model is filled out with the body of the request, but I would like to bind the <code>command.UserId</code> property using some values from the request headers (e.g. from a authentication token). </p>
  
  <p><strong>How can I bind the property of <code>IUserAware</code> from a request header value, with e.g. a model-binder, without having to create a binder for the concrete class <code>CreateSomething</code>?</strong></p>
  
  <p>I've tried various combinations of the <code>IModelBinder</code> interface in Web API, but with no real luck. </p>
  
  <p>It also feels redundant to to use:</p>
  
  <pre><code>[HttpPut, Route("create")]
  public IHttpActionResult CreateSomething([FromBody]CreateSomething command)
  {
      command.UserId = GetUserIdFromTheRequest();
  }
  </code></pre>
  
  <p>Or getting the <code>UserId</code> from a dependency on the controller and set it like the above.</p>
  
  <p><strong>How it is done in ASP.NET MVC</strong></p>
  
  <p>In ASP.NET MVC it is possible to do the following to get it work:</p>
  
  <pre><code>public class UserAwareModelBinder : DefaultModelBinder
  {
      protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, System.Type modelType)
      {
          var baseModel = base.CreateModel(controllerContext, bindingContext, modelType);
          var commandModel = baseModel as IUserAware;
          if (commandModel != null) 
          {
               commandModel.UserId = controllerContext.HttpContext.User; // or get it from the HttpContext headers.
          }
  
          return baseModel;
      }
  }
  </code></pre>
  
  <p>And wire it up at startup with:</p>
  
  <pre><code>ModelBinders.Binders.DefaultBinder = new UserAwareModelBinder();
  </code></pre>