mono-service WCF OPTIONS on rasbian
<p>I successfully created a self-hosted WCF mono-service on raspberry jessie, and it works (almost). </p>

<p>Versions </p>

<ul>
<li>Mono JIT compiler version 4.2.1 </li>
<li>Raspbian GNU/Linux 8 \n \l</li>
</ul>

<p>The problem is that Chrome web apps can't consume it, since it doesn't respond to any OPTIONS request. The request stays in <em>'pending'</em> state until I kill the service.</p>

<p>I really tried a lot of solutions related to CORS, but i think the problem might be a bit deeper. I think that way, because a OPTIONS request does not reach the CorsDispatchMessageInspector (3rd code fragment below).</p>

<p>The setup I currently have.</p>

<p>app.config</p>

<pre><code>&lt;startup&gt;
    &lt;supportedRuntime version="v4.5" sku=".NETFramework,Version=v4.5" /&gt;
&lt;/startup&gt;
&lt;system.serviceModel&gt; 
  &lt;services&gt;
    &lt;service name="AspaDeviceControlCenter.Fp550Module.Fp550Module"&gt;
      &lt;endpoint address="http://localhost:8111/json/fp550/" binding="webHttpBinding" behaviorConfiguration="jsonEndpointBehaviour" contract="AspaDeviceControlCenter.Fp550Module.IFp550Module"/&gt;
    &lt;/service&gt;
  &lt;/services&gt;
  &lt;behaviors&gt;
    &lt;serviceBehaviors&gt;
      &lt;behavior&gt;
        &lt;serviceMetadata httpGetEnabled="true" /&gt;
      &lt;/behavior&gt;
    &lt;/serviceBehaviors&gt;
    &lt;endpointBehaviors&gt;
      &lt;behavior name="jsonEndpointBehaviour"&gt;
       &lt;webHttp/&gt;
       &lt;corsEndpointBehaviorExtension/&gt;
      &lt;/behavior&gt;
      &lt;behavior name="webscriptBehavior"&gt;
        &lt;enableWebScript/&gt;
      &lt;/behavior&gt;
    &lt;/endpointBehaviors&gt;
  &lt;/behaviors&gt;
  &lt;serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/&gt;
&lt;/system.serviceModel&gt;
&lt;system.webServer&gt;
  &lt;modules runAllManagedModulesForAllRequests="true"/&gt;
  &lt;directoryBrowse enabled="true"/&gt;
&lt;/system.webServer&gt;
&lt;extensions&gt;
  &lt;behaviorExtensions&gt;
    &lt;add name="corsEndpointBehaviorExtension" type="AspaDeviceControlCenter.Service.Hosting.CorsEndpointBehaviorExtension, AspaDeviceControlCenter.Service"/&gt;
  &lt;/behaviorExtensions&gt;
&lt;/extensions&gt;
</code></pre>

<p>I used EndpoinBehaviorExtension solution from <a href="http://enable-cors.org/server_wcf.html" rel="nofollow">enable-cors.org</a> to add required 'alow' headers to any OPTIONS request, but a breakpoint there does not fire for the OPTIONS requests, only for GET and POST</p>

<p>The extension actual part</p>

<pre><code>public class CorsEndpointBehaviorExtension : BehaviorExtensionElement, IEndpointBehavior
{
   /*some empty methods*/

   public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
   {
        var requiredHeaders = new Dictionary&lt;string, string&gt;();

        //requiredHeaders.Add("Access-Control-Allow-Origin", "*");
        requiredHeaders.Add("Access-Control-Request-Method", "POST,GET,PUT,DELETE,OPTIONS");
        requiredHeaders.Add("Access-Control-Allow-Headers", "Accept,Origin,Authorization,X-Requested-With,Content-Type,X-Tenant");

        endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new CorsDispatchMessageInspector(requiredHeaders));
   }
</code></pre>

<p>Now the part that should help and where i think that the problem there is a deeper one, maybe a OS configuration one, but I'm not a Linux expert.</p>

<pre><code>public class CorsDispatchMessageInspector: IDispatchMessageInspector
{
    Dictionary&lt;string, string&gt; requiredHeaders;

    public CorsDispatchMessageInspector(Dictionary&lt;string, string&gt; headers)
    {
        requiredHeaders = headers ?? new Dictionary&lt;string, string&gt;();
    }

    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        return null;
    }
    public void BeforeSendReply(ref Message reply,object correlationState)
    {

        var httpHeader = reply.Properties["httpResponse"] as HttpResponseMessageProperty;
        foreach (var item in requiredHeaders)
        {
            httpHeader.Headers.Add(item.Key, item.Value);
        }        
    }
}
</code></pre>

<p>Both AfterReceiveRequest and BeforeSendReply has breakpoints, and they break when, I send a POST / GET, but not when the request method is OPTIONS</p>

<p>The service contract interface. I have lots of different operation contracts defined to test what I have found on the internet so far. None of those responded to OPTIONS request.</p>

<pre><code>[ServiceContract]
public interface IFp550Module : IControlCenterModule
{
    [OperationContract]
    bool Init();

    [OperationContract]
    [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
    string Open(/*int port, string settings*/);

    [OperationContract]
    [WebInvoke(Method = "*", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
    string Version();

    [OperationContract]
    [WebInvoke(Method = "OPTIONS", UriTemplate="*", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
    bool GetOptions();
}
</code></pre>

<p>No error callback breaks during runtime.</p>

<pre><code>var host = new ServiceHost(module);
_serviceHosts.Add(host);
host.Faulted += OnFaulted;
host.UnknownMessageReceived += OnUnknownMessageReceived;
host.Opening += module.ServiceStarting;
host.Closing += module.ServiceClosing;
host.Open();
</code></pre>

<p>I also tried my own CustomTextMessageEncoder : MessageEncoder, and public override Message ReadMessage method breakpoint was hit only for GET/POST. How deep I must go hit that OPTIONS request breakpoint? Or maybe is it just some flag somewhere in mono-service.</p>

<p>Also when I stop my service all pending options requests returns network error.</p>

<p>And when I start the request and then send a any request (including OPTIONS) there is a "Thread started:  #16" message in the application output, so it seems that the OPTIONS request reaches 'the application level'.</p>

<p>The next step deeper would be my own ServiceHost class and channel listener, but that is a ton of work and it could be that the problem is not even in application level anyway.</p>

<p>Let me know if I miss something. I use this question as my last resort.</p>