Как решить WCF Rest MethodNotFound (405) Ошибка при применении к PUT через WCF Rest Starter Kit HttpClient - PullRequest
2 голосов
/ 02 сентября 2010

Я рассмотрел почти все проблемы WCF Rest PUT / POST в SO и до сих пор не смог определить, почему я не могу PUT или POST для своего веб-сервиса, но могу вызвать тестовый метод GetTime через GET.

Эта конкретная служба обменивает пользовательскую учетную информацию (имя пользователя, пароль и некоторую другую информацию) для токена. Эта информация о токене зашифрована и добавлена ​​в заголовок последующих запросов к другим веб-службам, так что имя пользователя / пароли не нужно передавать везде.

Все вызовы веб-службы по-прежнему обрабатываются как не имеющие состояния, но для доступа к защищенным операциям службы требуется эта информация заголовка аутентификации, а не имя пользователя / пароли.

Договор

[ServiceContract(Namespace = "")]
public interface IUserService
{
    [WebInvoke(Method = "PUT", UriTemplate = "users/{username}/session")]
    [WebHelp(Comment = "Creates a new session for the specified username")]
    [OperationContract]
    AuthToken PutSession(string username, CustomCredential credential);
   ...

    [WebInvoke(Method = "GET", UriTemplate = "time")]
    [WebHelp(Comment = "Test method; returns the time")]
    [RequireAuthToken]
    [OperationContract]
    DateTime GetTime();
}

Реализация услуг

public class UserService : IUserService
{
    #region UserService Members
    public AuthToken PutSession(string username, CustomCredential credential)
    {
      // ...
    }

    public DateTime GetTime()
    {
        return DateTime.Now;
    }
}

Тестовый код

    [Fact]
    public void When_Authenticated_And_Getting_Time_Expect_200_Status()
    {
        // arrange
        using (var client = Get_HttpClient_With_AuthHeaders()) {

            // act
            var result = client.Get("time");

            // assert
            Assert.Equal(HttpStatusCode.OK, result.StatusCode);
        }
    } 

Вышеупомянутый GetTime работает (я добавил только тестовый метод).

    [Fact]
    public void When_PuttingSession_Expect_AuthToken_Is_Returned()
    {
        // arrange
        using (var client = Get_HttpClient_With_No_Auth_Headers()) {

            var cred = new CustomCredential("test", "password", 1);
            var content = HttpContentExtensions.CreateDataContract<CustomCredential>(cred);

            // act
            HttpResponseMessage response = client.Put("users/test/session", content);

            // assert
            response.EnsureStatusIsSuccessful();
            Assert.Equal(HttpStatusCode.Created, response.StatusCode);
            var authToken = response.Content.ReadAsDataContract<AuthToken>();
            Assert.NotNull(authToken);
        }
    }

Приведенный выше код возвращает MethodNotAllowed (405) .

Так же, как еще один тест, я добавил конечную точку Mex к службе, создал новое консольное приложение и добавил «ссылку на службу» к этой службе. Используя сгенерированный клиентский прокси-код, я смог что-то похожее на ....

IUserServiceClient client = new IUserServiceClient();
CustomCredential cred = ...
AuthToken token = client.PutSession("test_username", cred);

Что это говорит о том, что ...

  • Веб-сервис правильно размещен в IIS
  • Я могу использовать службу с использованием кода, сгенерированного прокси-сервером клиента SOAP
  • Я могу получать запросы GET через более дружественный инструментарий HttpClient / rest
  • Я протестировал это получить в браузере, и он работает
  • По какой-то причине put и другие связанные методы (post, delete и т. Д.) Не работают через остальные инструменты

Понятия не имею, что является причиной этого.

EDIT

Я также заметил, что IIS должен был создать этот файл web.config в корне веб-сайта, на котором размещены сервисы, что, по-видимому, позволяет использовать основные HTTP-глаголы.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <security>
            <requestFiltering>
            <verbs>
                <add verb="PUT" allowed="true" />
                <add verb="GET" allowed="true" />
                <add verb="POST" allowed="true" />
                <add verb="DELETE" allowed="true" />
            </verbs>
            <fileExtensions>
                <add fileExtension=".svc" allowed="true" />
            </fileExtensions>
        </requestFiltering>
        </security>
    </system.webServer>
</configuration>

Я также проверил в IIS 7 сопоставления обработчиков для * .svc и проверил, включены ли «все глаголы».

1 Ответ

1 голос
/ 02 сентября 2010

Убедитесь, что связанный обработчик для .svc в IIS может обрабатывать HTTP POST, PUT, DELETE.В случае проблем только с PUT и DELETE убедитесь, что ваш виртуальный каталог не настроен для WebDAV (я думаю, что это какой-то модуль HTTP).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...