【问题标题】:CORS on Self Hosted WCF Service自托管 WCF 服务上的 CORS
【发布时间】:2019-07-30 14:27:21
【问题描述】:

我正在尝试在我的 WCF 服务中实现 CORS 支持。

我从

那里得到了一些代码

https://enable-cors.org/server_wcf.html

public class CustomHeaderMessageInspector : IDispatchMessageInspector
        {
            Dictionary<string, string> requiredHeaders;
            public CustomHeaderMessageInspector (Dictionary<string, string> headers)
            {
                requiredHeaders = headers ?? new Dictionary<string, string>();
            }

            public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
            {
                return null;
            }

            public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
            {
                var httpHeader = reply.Properties["httpResponse"] as HttpResponseMessageProperty;
                foreach (var item in requiredHeaders)
                {
                    httpHeader.Headers.Add(item.Key, item.Value);
                }           
            }
        }

但我在这一行收到错误消息

public class CustomHeaderMessageInspector : IDispatchMessageInspector

错误:类只能从其他类继承

如何继承IDispatchMessageInspector

谢谢

【问题讨论】:

  • 您是否包含了对 System.ServiceModel.Dispatcher 的引用
  • 是的。包含 System.ServiceModel.Dispatcher
  • 我能从错误消息中获得的唯一参考来自docs.microsoft.com/en-us/dotnet/visual-basic/misc/bc30258
  • @mahlatse 谢谢。但我无法理解网页上提供的解决方案

标签: wcf self hosted idispatchmessageinspector


【解决方案1】:

你应该添加

Dim method = httpRequest.Method
If method.ToLower() = "options" Then httpResponse.StatusCode = System.Net.HttpStatusCode.NoContent

在 BeforeSendReply 结束时添加您的示例,否则至少 POST 请求将不起作用。

【讨论】:

    【解决方案2】:

    我做了一个demo,希望对你有用。
    参考。

    using System;
    using System.Collections.Generic;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Configuration;
    using System.ServiceModel.Description;
    using System.ServiceModel.Dispatcher;
    using System.ServiceModel.Web;
    

    服务器。

    class Program
        {
            static void Main(string[] args)
            {
                using (ServiceHost sh = new ServiceHost(typeof(MyService)))
                {
                    sh.Open();
                    Console.WriteLine("service is ready...");
                    Console.ReadLine();
                    sh.Close();
                }
    
            }
        }
        [ServiceContract(Namespace = "mydomain")]
        public interface IService
        {
            [OperationContract]
            [WebGet(ResponseFormat =WebMessageFormat.Json)]
            string SayHello();
        }
        public class MyService : IService
        {
            public string SayHello()
            {
                return $"Hello, busy World,{DateTime.Now.ToShortTimeString()}";
            }
        }
        public class CustomHeaderMessageInspector : IDispatchMessageInspector
        {
            Dictionary<string, string> requiredHeaders;
            public CustomHeaderMessageInspector(Dictionary<string, string> headers)
            {
                requiredHeaders = headers ?? new Dictionary<string, string>();
            }
            public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
            {
                string displayText = $"Server has received the following message:\n{request}\n";
                Console.WriteLine(displayText);
                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);
                }
    
                string displayText = $"Server has replied the following message:\n{reply}\n";
                Console.WriteLine(displayText);
    
            }
        }
        public class CustomContractBehaviorAttribute : BehaviorExtensionElement, IEndpointBehavior
        {
            public override Type BehaviorType => typeof(CustomContractBehaviorAttribute);
    
            public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
            {
            }
    
            public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
            {
            }
    
            public void ApplyDispatchBehavior(ServiceEndpoint endpoint, 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", "X-Requested-With,Content-Type");
    
                endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new CustomHeaderMessageInspector(requiredHeaders));
            }
    
            public void Validate(ServiceEndpoint endpoint)
            {
    
            }
    
    
            protected override object CreateBehavior()
            {
                return new CustomContractBehaviorAttribute();
            }
        }
    

    App.config

    <system.serviceModel>
        <services>
          <service name="Server3.MyService" behaviorConfiguration="mybahavior">
            <endpoint address="" binding="webHttpBinding" contract="Server3.IService" behaviorConfiguration="rest"></endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:5638"/>
              </baseAddresses>
            </host>
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior name="mybahavior">
              <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
              <serviceDebug includeExceptionDetailInFaults="true"/>
            </behavior>
          </serviceBehaviors>
          <endpointBehaviors>
            <behavior name="rest">
              <webHttp />
              <CorsBehavior />
            </behavior>
          </endpointBehaviors>
        </behaviors>
        <extensions>
          <behaviorExtensions>
            <add name="CorsBehavior" type="Server3.CustomContractBehaviorAttribute, Server3" />
          </behaviorExtensions>
        </extensions>
      </system.serviceModel>
    

    客户。

        <script>
        $(function(){
            $.ajax({
                method:"Get",
                url: "http://10.157.13.69:5638/sayhello",
                dataType:"json",
                success: function(data){
                    $("#main").html(data);
                }
            })
        })
    </script>
    

    结果

    如果有什么可以帮助的,请随时告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-07
      • 1970-01-01
      • 1970-01-01
      • 2013-06-09
      • 1970-01-01
      相关资源
      最近更新 更多