【问题标题】:WCF Self Host Service Calling with Ajax : 405 Method Not Allowed Error使用 Ajax 调用 WCF 自托管服务:405 方法不允许错误
【发布时间】:2019-10-27 01:39:14
【问题描述】:

在发布这个问题之前,我已经浏览了很多类似的帖子,但找不到解决方案。

我在 WinForms 应用程序中有一个自托管 WCF 服务。

代码:

[ServiceContract]
public interface IMathService
{
    [WebInvoke(Method = "GET",
        UriTemplate = "Add/{num1}",
        RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json)]
    [OperationContract]
    int Add(string num1);
}

public class MathService : IMathService
{
    public int Add(string num1)
    {
        return Convert.ToInt32(num1) + 1;
    }
}
public Form1()
{
    InitializeComponent();
    WebServiceHost testHost = new WebServiceHost(typeof(MathService));
    testHost.Open();

}

App.Config:

<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
  </startup>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="EndpBehavior">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="ServiceBehavior" name="S3SelfHost.MathService">
        <endpoint address="http://localhost:8181/MathService" binding="webHttpBinding"

            contract="S3SelfHost.IMathService" behaviorConfiguration="EndpBehavior"/>
      </service>
    </services>
  </system.serviceModel>
</configuration>

我有一个普通的 html 页面和一个 js 文件,我试图从中调用这个仅在我的本地机器上运行的服务。

JS:

$("#btnAdd").click(function () {
    jQuery.support.cors = true;
    $.ajax({
        type: "POST",
        contentType: "application/json; charset=UTF-8; charset-uf8",
        url: 'http://localhost:8181/MathService/Add/1',
        success: function (data) {
            $("#result").val(result);
        },
        error: function (result) {
            alert(result);
        }
    });

});

如果我直接在浏览器中点击托管 url,那么它会显示正确的结果,但是当我在 js 代码中使用相同的 url 时,它会在控制台中显示以下错误。

在“http://localhost:8181/MathService/Add/1”访问 XMLHttpRequest 来自原点“http://localhost”已被 CORS 策略阻止: 对预检请求的响应未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。

在提琴手响应标头中显示

405 方法不允许

【问题讨论】:

    标签: ajax wcf cross-domain self-hosting http-status-code-405


    【解决方案1】:

    对于 WebHttpBinding 创建的自托管 WCF 服务,我们可以使用以下代码来启用对 CORS 的支持。
    参考。

        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;
    

    端点行为扩展。

    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, IClientChannel channel, 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 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-Max-Age", "1728000");
                requiredHeaders.Add("Access-Control-Request-Method", "POST,GET,PUT,DELETE,OPTIONS");
                requiredHeaders.Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, Pragma, Cache-Control");
                endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new CustomHeaderMessageInspector(requiredHeaders));
            }
    
            public void Validate(ServiceEndpoint endpoint)
            {
    
            }
    
            protected override object CreateBehavior()
            {
                return new CustomContractBehaviorAttribute();
            }
        }
    

    在服务端点中应用它。

          <endpointBehaviors>
            <behavior name="EndpBehavior">
              <webHttp/>
              <CorsBehavior />
            </behavior>
          </endpointBehaviors>
        </behaviors>
        <services>
          <service behaviorConfiguration="ServiceBehavior" name="YourNamespace.MathService">
            <endpoint address="http://localhost:8181/MathService" binding="webHttpBinding"
                contract="YourNamespace.IMathService" behaviorConfiguration="EndpBehavior"/>
          </service>
        </services>
        <extensions>
          <behaviorExtensions>
            <add name="CorsBehavior" type="YourNamespace.CustomContractBehaviorAttribute, YourNamespace" />
          </behaviorExtensions>
        </extensions>
      </system.serviceModel>
    

    客户。

                    //10.157.13.70 is the host that runs the Winform application.
       var serviceuri = "http://10.157.13.70:8181/MathService/add/34";
                $.ajax({
                    method:"Get",
                    url:serviceuri,
                    //contentType:"application/x-www-form-urlencoded",
                    success:function(data){
                        console.log(data);
                    }
                }).done(function(data){
                    console.log(data);
                }).fail(function(jqxhr,textstatus,err){
                    console.log(err);
                })
    

    结果。
    如果问题仍然存在,请随时告诉我。

    【讨论】:

    • 我已经尝试过使用“POST”和“GET”方法,但仍然无法正常工作。我不确定,但可能 部分仅在我在 IIS 上托管服务时才有效。
    • 是的,你是对的。没有注意到你的托管环境,我已经更改了回复,请尝试上面的代码。如果有什么可以帮助的,请随时告诉我。
    • 另外,请注意汇编参考。
    猜你喜欢
    • 2014-03-30
    • 2011-03-04
    • 2013-03-15
    • 1970-01-01
    • 2012-10-25
    • 2015-11-20
    • 2019-09-08
    • 2016-06-13
    • 2011-01-13
    相关资源
    最近更新 更多