Удалить не работает в выбрасывании службы отдыха WCF (405) Метод не разрешен - PullRequest
3 голосов
/ 05 декабря 2011

Я создал сервис WCF RESTful, который использует простую базу данных и просто пытается работать над помещением, получением, публикацией и удалением элементов.Прямо сейчас отправьте, положите и получите работает.Но удаление не работает.Некоторые форумы говорят, что мне нужно отключить модуль WebDAV.Я сделал это, а затем я получил PUT на работу.Но я не могу заставить УДАЛИТЬ работать.Всякий раз, когда я вызываю команду DELETE через свой сервис, я получаю следующую ошибку:

Удаленный сервер возвращает неожиданный ответ: (405) Метод не разрешен.

Может ли кто-нибудь помочь мне в этом?

Ответы [ 4 ]

2 голосов
/ 15 ноября 2012

Я еще не нашел одного исчерпывающего ответа для переопределения PUT и DELETE и возврата 405-х для остальных WCF-сервисов в других местах, поэтому я опубликую его здесь.

Эту проблему можно легко решить, просто удалив 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. Но, надеюсь, это поможет.

0 голосов
/ 05 сентября 2014

Добавление кодов в файл 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();
0 голосов
/ 10 мая 2012

Я использовал подход WebChannelFactory на стороне клиента для использования службы REST.Я создал ссылку на службу, используя обычный подход «Добавить ссылку на службу».Это не добавляет [WebGet(UriTemplate = "/")].

После того, как я добавил их для всех прокси-классов Операции на стороне Клиента, так же как и Договор на обслуживание, он начал работать.

0 голосов
/ 05 декабря 2011
...