删除不在WCF休息服务中工作throw(405)方法不允许

时间:2011-12-05 15:04:03

标签: rest

我创建了WCF RESTful服务,它使用简单的数据库,只是尝试处理put,get,post和delete项目。现在发布,put和get工作正常。但删除是行不通的。一些论坛告诉我需要禁用WebDAV模块。我做到了,然后我得到PUT工作。但我不能让DELETE工作。每当我通过我的服务调用DELETE动词时,我都会收到以下错误:

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

任何人都可以帮我吗?

4 个答案:

答案 0 :(得分:2)

我还没有找到一个全面的答案,PUT和DELETE被覆盖,并在其他任何地方为宁静的WCF服务返回405s,所以我将在这里发布。

只需通过角色管理器(在服务器上)或通过添加/删除窗口功能从计算机上卸载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。但希望这会有所帮助。

答案 1 :(得分:0)

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

将代码添加到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();