【问题标题】:Delete not Working in WCF rest service throwing (405) Method Not Allowed删除不工作在 WCF 休息服务抛出 (405) 方法不允许
【发布时间】:2012-01-13 07:25:46
【问题描述】:

我创建了 WCF RESTful 服务,它使用简单的数据库,只是尝试处理放置、获取、发布和删除项目。现在发布,放置和获取正在工作。但是删除不起作用。一些论坛告诉我需要禁用 WebDAV 模块。我这样做了,然后我让 PUT 开始工作。但我无法让 DELETE 工作。每当我通过我的服务调用 DELETE 动词时,我都会收到以下错误:

远程服务器返回意外响应:(405) Method Not Allowed。

谁能帮我解决这个问题?

【问题讨论】:

    标签: rest


    【解决方案1】:

    【讨论】:

      【解决方案2】:

      我在客户端使用WebChannelFactory 方法来使用REST 服务。我使用普通的“添加服务参考”方法创建了服务参考。这不会添加[WebGet(UriTemplate = "/")]

      在我为客户端代理类上的所有操作添加这些之后,就像服务合同一样,它开始工作了。

      【讨论】:

        【解决方案3】:

        我还没有找到一个全面的答案来解决 PUT 和 DELETE 被覆盖并在其他任何地方返回 405 以获得宁静的 WCF 服务,所以我将在此处发布。

        通过角色管理器(在服务器上)或通过添加/删除 Windows 功能从机器上卸载 WebDAV 即可轻松解决此问题。如果这是可以接受的方法,您现在可以停止阅读。

        这里通常推荐的修复方法是简单地从您的站点中删除 WebDAV 模块,将以下内容附加到您的 web.config:

          <system.webServer>
                <modules>
                    <remove name="WebDAVModule" />
                </modules>
          </system.webServer>
        

        这里的问题是,现在您的 WCF 应用程序根本无法知道如何处理 PUT 和 DELETE。所以为了解决这个问题,一些解决方案建议进行以下修改:

        <modules runAllManagedModulesForAllRequests="true">
         <system.webServer>
               <modules>
                   <remove name="WebDAVModule" />
               </modules>
         </system.webServer>
        

        这对大多数人来说可能是令人满意的,但我不喜欢让我们的服务在不必要的时候为每次调用无用地加载所有内容的想法。因此,我通过手动将无扩展 URL 处理程序映射到所有 HTTP 动词来稍微改进了该方法(可能可以改进为必要的)

          <system.webServer>
                <modules>
                    <remove name="WebDAVModule" />
                </modules>
                <handlers>
                    <remove name="WebDAV" />
                    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
                    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" />
                </handlers>
          </system.webServer>
        

        我只在 R2 64 和 7 64 上测试过这个,所以 ymmv。但希望这会有所帮助。

        【讨论】:

          【解决方案4】:

          向 Web.config 文件添加代码

          <?xml version="1.0" encoding="utf-8"?>
          <configuration>
              <configSections>
                  <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
              </configSections>
              <appSettings>
                  <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
              </appSettings>
              <system.web>
                  <compilation debug="true" targetFramework="4.5" />
                  <httpRuntime targetFramework="4.5" />
              </system.web>
              <system.serviceModel>
                  <behaviors >
                      <serviceBehaviors>
                          <behavior  name="http">
                              <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                              <serviceDebug includeExceptionDetailInFaults="true" />
                          </behavior>
                      </serviceBehaviors>
                      <endpointBehaviors>
                          <behavior name="www">
                              <webHttp/>
                          </behavior>
                      </endpointBehaviors>
                  </behaviors>
                  <protocolMapping>
                      <add binding="basicHttpsBinding" scheme="https" />
                  </protocolMapping>
                  <services>
                      <service behaviorConfiguration="http" name="REST.CRUD.Alternativ">
                          <endpoint address=""
                                              binding="webHttpBinding"
                                              behaviorConfiguration="www"
                                              contract="REST.CRUD.IAlternativ"
                                              bindingConfiguration="rest">
                          </endpoint>
                          <endpoint address="mex"
                                              binding="mexHttpBinding"
                                              contract="IMetadataExchange">
                          </endpoint>
                      </service>
                  </services>
                  <bindings>
                      <webHttpBinding>
                          <binding allowCookies="true" name="rest">
                              <security mode="None"></security>
                          </binding>
                      </webHttpBinding>
                  </bindings>
                  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
              </system.serviceModel>
              <system.webServer>
                  <modules runAllManagedModulesForAllRequests="true" />
                  <directoryBrowse enabled="true" />
                  <security>
                      <requestFiltering>
                          <verbs>
                              <add verb="GET" allowed="true" />
                              <add verb="POST" allowed="true" />
                              <add verb="DELETE" allowed="true" />
                              <add verb="PUT" allowed="true" />
                          </verbs>
                      </requestFiltering>
                  </security>
              </system.webServer>
              <entityFramework>
                  <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
                      <parameters>
                          <parameter value="v11.0" />
                      </parameters>
                  </defaultConnectionFactory>
                  <providers>
                      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
                  </providers>
              </entityFramework>
              <connectionStrings>
                  <add name="KendoDB" connectionString="Data Source=(localDB)\v11.0;Initial Catalog=Kendo;Integrated Security=True;Pooling=False" providerName="System.Data.SqlClient" />
              </connectionStrings>
          </configuration>
          

          PersonDTO

          using System;
          using System.Collections.Generic;
          using System.Linq;
          using System.Web;
          using System.Data.Entity;
          
          namespace REST.CRUD
          {
              public class PersonDTO
              {
                  public int ID { get; set; }
                  public string firstName { get; set; }
                  public string lastName { get; set; }
              }
          
              public class KendoContext : DbContext
              {
                  public  KendoContext():base("KendoDB"){}
                  public DbSet<PersonDTO> PersonDTOs { get; set; }
              }
          }
          

          IAlternativ.cs

          using System;
          using System.Collections.Generic;
          using System.Linq;
          using System.Runtime.Serialization;
          using System.ServiceModel;
          using System.ServiceModel.Web;
          using System.Text;
          using System.Web.Services;
          
          
          namespace REST.CRUD
          {
              [ServiceContract]
              public interface IAlternativ
              {
                  [WebInvoke(Method = "POST",
                      BodyStyle = WebMessageBodyStyle.WrappedRequest,
                      RequestFormat = WebMessageFormat.Json,
                      ResponseFormat = WebMessageFormat.Json)]
                  [OperationContract]
                  List<PersonDTO> GetAll();
          
                  [WebInvoke(Method = "GET",
                      BodyStyle = WebMessageBodyStyle.WrappedRequest,
                      RequestFormat = WebMessageFormat.Json,
                      ResponseFormat = WebMessageFormat.Json)]
                  [OperationContract]
                  PersonDTO Get(int ID, string f, string l);
          
                  [WebInvoke(Method = "DELETE", 
                      BodyStyle = WebMessageBodyStyle.WrappedRequest,
                      RequestFormat = WebMessageFormat.Json,
                      ResponseFormat = WebMessageFormat.Json)]
                  [OperationContract]
                  String Delete(int ID, string f, string l);
          
                  [WebInvoke(Method = "PUT", 
                      BodyStyle = WebMessageBodyStyle.WrappedRequest,
                      RequestFormat = WebMessageFormat.Json,
                      ResponseFormat = WebMessageFormat.Json)]
                  [OperationContract]
                  String Update(int ID, string f, string l);
              }
          }
          

          Alternativ.svc.cs

          using System;
          using System.Collections.Generic;
          using System.Linq;
          using System.Runtime.Serialization;
          using System.ServiceModel;
          using System.Text;
          using System.Web.Script.Services;
          using System.Web.Services;
          
          
          namespace REST.CRUD
          {
              public class Alternativ : IAlternativ
              {
                  public List<PersonDTO> GetAll()
                  {
                      var db = new KendoContext();
                      return db.PersonDTOs.Select(c => c).ToList();
                  }
          
                  public PersonDTO Get(int ID, string f, string l)
                  {
                      var db = new KendoContext();
                      return db.PersonDTOs.Where(c => c.ID == ID).Select(c => c).First();
                  }
          
                  public String Delete(int ID, string f, string l)
                  {
                      //Delete Code
                      return "OK";
                  }
          
                  public String Update(int ID, string f, string l)
                  {
                      //Update Code
                      return "OK";
                  }
              }
          }
          

          [构建并运行 WCF 项目(F5)]。

          将 jquery 添加到 DOM 以进行测试(粘贴到控制台)

          (function() {
            if (! window.jQuery ) {
              var s = document.createElement('script');
              s.type = 'text/javascript';
              s.async = true;
              s.src = '//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js'; 
              (document.getElementsByTagName('head')[0] ||
                document.getElementsByTagName('body')[0]).appendChild(s);
            }
          }());
          

          向控制台添加功能

          function POST(){
          $.ajax({
                type: "POST", //GET,POST,PUT or DELETE verb
                url: "/Alternativ.svc/GetAll", // Location of the service
                data: '{"ID":"1"}', //Data to be sent to server
                dataType: "json", // content type sent to server
                contentType: "application/json; charset=utf-8", //Expected data format from server
                processdata: false, //True or False
                success: function (response) {
                  console.log(response);
                },
                error: function (xhr, ajaxOptions, thrownError) {
                  alert(xhr.statusText);
                }
          });
          }
          function GET(){
          $.ajax({
                type: "GET", //GET,POST,PUT or DELETE verb
                url: "/Alternativ.svc/Get", // Location of the service
                data: {ID:1}, //Data to be sent to server
                dataType: "json", // content type sent to server
                contentType: "application/json; charset=utf-8", //Expected data format from server
                processdata: true, //True or False
                success: function (response) {
                  console.log(response);
                },
                error: function (xhr, ajaxOptions, thrownError) {
                  alert(xhr.statusText);
                }
          });
          }
          function DELETE(){
          $.ajax({
                type: "DELETE", //GET,POST,PUT or DELETE verb
                url: "/Alternativ.svc/Delete", // Location of the service
                data: '{"ID":"1"}', //Data to be sent to server
                dataType: "json", // content type sent to server
                contentType: "application/json; charset=utf-8", //Expected data format from server
                processdata: false, //True or False
                success: function (response) {
                  console.log(response);
                },
                error: function (xhr, ajaxOptions, thrownError) {
                  alert(xhr.statusText);
                }
          });
          }
          function PUT(){
          $.ajax({
                type: "PUT", //GET,POST,PUT or DELETE verb
                url: "/Alternativ.svc/Update", // Location of the service
                data: '{"ID":"1"}', //Data to be sent to server
                dataType: "json", // content type sent to server
                contentType: "application/json; charset=utf-8", //Expected data format from server
                processdata: false, //True or False
                success: function (response) {
                  console.log(response);
                },
                error: function (xhr, ajaxOptions, thrownError) {
                  alert(xhr.statusText);
                }
          });
          }
          

          调用函数

          DELETE();
          PUT();
          GET();
          POST();
          

          【讨论】:

            猜你喜欢
            • 2016-06-13
            • 2011-01-13
            • 2017-10-10
            • 1970-01-01
            • 1970-01-01
            • 2013-03-15
            • 2014-12-29
            相关资源
            最近更新 更多