WCF:在GET工作时,POST请求被拒绝(错误405)

时间:2018-01-14 16:20:55

标签: c# wcf post

我正在尝试使用WCF进行POST / GET服务。我在哪里遇到没有问题的GET,我的POST服务总是得到错误405.我搜索了这么多帖子,但没有找到让它工作的东西。我现在不知道该尝试什么。

这是我的合同:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

using System.ServiceModel.Web;
using System.ComponentModel;

namespace DemoService
{
    #region Service contract
    [ServiceContract]
    [ServiceKnownType(typeof(DbElement))]
    public interface IDatabaseService
    {
        #region Services
        [OperationContract]
        [WebInvoke(Method = "GET",
                ResponseFormat = WebMessageFormat.Json,
                UriTemplate = "description/{elementID}")]
        [Description("Get description of an element, identified in database by its Id")]
        DbElement GetElementDescription(string elementId);


        [OperationContract]
        [WebInvoke(Method = "POST",
                RequestFormat = WebMessageFormat.Json,
                ResponseFormat = WebMessageFormat.Json,
                UriTemplate = "update/description/{Id}")]
        [Description("Update description of an element, using its id")]
        int UpdateElementName(string Id, DbElement Ident);
        #endregion
    }
    #endregion

    #region Service data
    [DataContract]
    public class DbElement
    {
        #region Properties
        [DataMember(Order = 1)]
        public string Name { get; set; }
        [DataMember(Order = 0)]
        public short SerialNumber { get; set; }
        #endregion

        internal DbElement()
        {
            SerialNumber = 0;
            Name = string.Empty;
        }
    }
    #endregion
}

我的web.config文件如下所示:

<?xml version="1.0"?>
<configuration>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
    </startup>

    <system.web>
        <compilation debug="true"/>
    </system.web>

    <!-- Following section is to be duplicated in exe app.config file (for the moment) -->
    <system.serviceModel>
        <services>
            <service name="DemoService.DatabaseService" behaviorConfiguration="baseServiceBehavior">
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8666/1.0"/>
                    </baseAddresses>
                </host>
                <endpoint address="REST"
                          binding="webHttpBinding"
                          behaviorConfiguration="web"
                          bindingConfiguration="webHttpBindingConfiguration"
                          contract="DemoService.IDatabaseService" />
            </service>
        </services>
        <bindings>
            <webHttpBinding>
                <binding name="webHttpBindingConfiguration" />
            </webHttpBinding>
        </bindings>
        <behaviors>
            <endpointBehaviors>
                <behavior name="web">
                    <webHttp defaultOutgoingResponseFormat="Json" helpEnabled="true" />
                    <crossOriginResourceSharingBehavior />
                </behavior>
            </endpointBehaviors>
            <serviceBehaviors>
                <behavior name="baseServiceBehavior">
                    <serviceMetadata httpGetEnabled="true"/>
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <extensions>
            <behaviorExtensions>
                <add name="crossOriginResourceSharingBehavior"
                     type="DemoService.EnableCrossOriginResourceSharingBehavior, DemoService" />
            </behaviorExtensions>
        </extensions>
    </system.serviceModel>
</configuration>

我使用的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 EnableCrossOriginResourceSharingBehavior : BehaviorExtensionElement, IEndpointBehavior
    {
        public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {

        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
        {

        }

        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-Methods", "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)
        {

        }

        public override Type BehaviorType
        {
            get { return typeof(EnableCrossOriginResourceSharingBehavior); }
        }

        protected override object CreateBehavior()
        {
            return new EnableCrossOriginResourceSharingBehavior();
        }
    }

我的测试客户是

<html></html>


<head>
        <script src="jquery.js"></script>
<script type="text/javascript">
  $(document).ready(function() {
    $("#jsonp2").click(function() {

      $.ajax({
        url: "http://localhost:8666/1.0/REST/update/description/2",
        data: "SerialNumber=321,Name:hello",
        type: "POST",
        contentType:"application/json",
        crossDomain:true,
        headers: { 'Content-Type': 'application/json; charset=UTF-8' },
        dataType: "json",
        success: function(data) {
          alert("Data from Server" + JSON.stringify(data));
        },
        error: function(jqXHR, textStatus, errorThrown) {
          alert("request failed: " + errorThrown);
        }
      });


    });
    $("#jsonp3").click(function() {

      $.ajax({
        url: " http://localhost:8666/1.0/REST/description/2",
        type: "GET",
        dataType: "json",
        success: function(data) {
          alert("Data from Server" + JSON.stringify(data));
        },
        error: function(jqXHR, textStatus, errorThrown) {
          alert("request failed: " + errorThrown);
        }
      });


    });
  });


</script>
</head>

<body>
<button id="jsonp2" type="button" class="btn btn-info">Send X Post Request</button>
<button id="jsonp3" type="button" class="btn btn-info">Send X Get Request</button>

</body>

</html>

调用GET服务工作得很好。 调用POST服务始终返回代码405而不到达入口点。

Couls有人帮我解决这个问题吗? 谢谢。

PS: 这是来自cient

的请求标头
Host :"localhost:8666"
User-Agent :"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0"
Accept :"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
Accept-Language :"fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3"
Accept-Encoding :"gzip, deflate"
Access-Control-Request-Method :"POST"
Access-Control-Request-Headers :"content-type"
Origin :"null"
DNT :"1"
Connection :"keep-alive"

和答案标题:

Access-Control-Allow-Headers :"X-Requested-With,Content-Type"
Access-Control-Allow-Origin :"*"
Access-Control-Request-Methods :"POST,GET,PUT,DELETE,OPTIONS"
Allow :"POST"
Content-Length :"1721"
Content-Type :"text/html; charset=UTF-8"
Date :"Mon, 15 Jan 2018 08:28:17 GMT"
Server :"Microsoft-HTTPAPI/2.0"

我准备了一个简单的项目来测试我的服务:也许它会让人们更容易找出我的实现有什么问题。该项目的链接是here

感谢任何额外帮助

0 个答案:

没有答案