Я успешно создал самостоятельный WCF-моносервис на малиновой jessie, и он работает (почти).mono-service WCF OPTIONS на rasbian
Версии
- Mono версии JIT компилятор 4.2.1
- Raspbian GNU/Linux 8 \ п \ л
Проблема заключается в том, что Chrome веб-приложения не могут потреблять его, так как он не отвечает на любой запрос OPTIONS. Запрос остается в «ожидающий», пока я не убью службу.
Я действительно пробовал много решений, связанных с CORS, но я думаю, что проблема может быть немного глубже. Я так думаю, потому что запрос OPTIONS не доходит до CorsDispatchMessageInspector (третий фрагмент кода ниже).
Установки, которые у меня есть.
app.config
<startup>
<supportedRuntime version="v4.5" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<services>
<service name="AspaDeviceControlCenter.Fp550Module.Fp550Module">
<endpoint address="http://localhost:8111/json/fp550/" binding="webHttpBinding" behaviorConfiguration="jsonEndpointBehaviour" contract="AspaDeviceControlCenter.Fp550Module.IFp550Module"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="jsonEndpointBehaviour">
<webHttp/>
<corsEndpointBehaviorExtension/>
</behavior>
<behavior name="webscriptBehavior">
<enableWebScript/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
<extensions>
<behaviorExtensions>
<add name="corsEndpointBehaviorExtension" type="AspaDeviceControlCenter.Service.Hosting.CorsEndpointBehaviorExtension, AspaDeviceControlCenter.Service"/>
</behaviorExtensions>
</extensions>
Я использовал EndpoinBehaviorExtension решение от enable-cors.org для добавления требуется «Alow» заголовки в любой запрос OPTIONS, но точка останова там не срабатывает для запросов OPTIONS, только GET и POST
расширение фактическая часть
public class CorsEndpointBehaviorExtension : BehaviorExtensionElement, IEndpointBehavior
{
/*some empty methods*/
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{
var requiredHeaders = new Dictionary<string, string>();
//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));
}
Теперь та часть, которая должна помочь и где я думаю, что проблема, с re является более глубоким, возможно, конфигурацией ОС, но я не эксперт по Linux.
public class CorsDispatchMessageInspector: IDispatchMessageInspector
{
Dictionary<string, string> requiredHeaders;
public CorsDispatchMessageInspector(Dictionary<string, string> headers)
{
requiredHeaders = headers ?? new Dictionary<string, string>();
}
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);
}
}
}
Оба AfterReceiveRequest и BeforeSendReply имеет контрольные точки, и они ломаются, когда я отправить POST/GET, но не тогда, когда метод запроса OPTIONS
Контракт интерфейс сервиса. У меня есть много разных контрактов на работу, определенных для проверки того, что я нашел в Интернете до сих пор. Ни один из них не ответил на запрос OPTIONS.
[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();
}
В процессе работы не происходит перехват обратных вызовов.
var host = new ServiceHost(module);
_serviceHosts.Add(host);
host.Faulted += OnFaulted;
host.UnknownMessageReceived += OnUnknownMessageReceived;
host.Opening += module.ServiceStarting;
host.Closing += module.ServiceClosing;
host.Open();
Я также попробовал свои собственные CustomTextMessageEncoder: MessageEncoder и общественное переопределение Сообщение метод ReadMessage точки останова был подбит только для GET/POST. Насколько глубоко я должен ударить, что точка останова запроса OPTIONS? Или, может быть, это просто какой-то флаг где-то в моносервисе.
Также, когда я останавливаю свое обслуживание, все ожидающие запросы параметров возвращают сетевую ошибку.
И когда я запускаю запрос, а затем отправляю любой запрос (включая ОПЦИИ), в выводе приложения появляется сообщение «Thread started: # 16», поэтому кажется, что запрос OPTIONS достигает «уровня приложения».
Следующим шагом будет мой собственный класс ServiceHost и прослушиватель каналов, но это тонна работы, и может случиться так, что проблема даже не на уровне приложений.
Сообщите мне, если я пропущу что-то. Я использую этот вопрос в качестве своего последнего средства.