HttpOperationHandlerFactory и InputParameters проблема - PullRequest
1 голос
/ 26 июля 2011

Я написал собственный OperationHandler для моего проекта WCF WebAPI следующим образом:

public class AuthenticationOperationHandler : HttpOperationHandlerFactory
{
    protected override Collection<HttpOperationHandler> OnCreateRequestHandlers(ServiceEndpoint endpoint, HttpOperationDescription operation)
    {
        var baseHandlers = base.OnCreateRequestHandlers(endpoint, operation);

        if (operation.InputParameters.Where(p => p.Name.ToLower() == "username").Any() &&
            operation.InputParameters.Where(p => p.Name.ToLower() == "password").Any())
        {
            baseHandlers.Add(new AuthenticateRequestHandler(string.Format("{0}:{1}", operation.InputParameters.Where(p => p.Name == "username").First                           ().Name, operation.InputParameters.Where(p => p.Name == "password").First().Name)));
        }
        else
        {
            throw new WebFaultException(HttpStatusCode.Forbidden);
        }

        return baseHandlers;
    }
}

, а также этот пользовательский RequestHandler, который добавляется в конвейер:

public class AuthenticateRequestHandler : HttpOperationHandler<HttpRequestMessage, string>
{
    public AuthenticateRequestHandler(string outputParameterName)
        : base(outputParameterName)
    {
    }

    public override string OnHandle(HttpRequestMessage input)
    {
        var stringValue = input.Content.ReadAsString();
        var username = stringValue.Split(':')[0];
        var password = stringValue.Split(':')[1];

        var isAuthenticated = ((BocaMembershipProvider)Membership.Provider).ValidateUser(username, password);
        if (!isAuthenticated)
        {
            throw new WebFaultException(HttpStatusCode.Forbidden);
        }

        return stringValue;
    }
}

иэто моя реализация API:

[ServiceContract]
public class CompanyService
{
    [WebInvoke(UriTemplate = "", Method = "POST")]
    public bool Post(string username, string password)
    {
        return true;
    }
}

Моя конфигурация в файле Global.asax:

public static void RegisterRoutes(RouteCollection routes)
{
    var config = HttpHostConfiguration.Create().SetOperationHandlerFactory(new AuthenticationOperationHandler());
    routes.MapServiceRoute<AuthenticationService>("login", config);
    routes.MapServiceRoute<CompanyService>("companies", config);
}

При попытке отправить запрос POST в / companies я получаю следующее сообщение об ошибке:

HttpOperationHandlerFactory не может определить входной параметр, который должен быть связан с содержимым сообщения запроса для операции службы «Post».Если операция не ожидает содержимого в сообщении запроса, используйте метод HTTP GET с операцией.В противном случае убедитесь, что для одного входного параметра его свойство IsContentParameter установлено в значение «True» или указан тип, который можно назначить одному из следующих параметров: HttpContent, ObjectContent 1, HttpRequestMessage or HttpRequestMessage 1.

в этой строке:

var baseHandlers = base.OnCreateRequestHandlers(endpoint, operation);

Есть идеи, почему это происходит и как это исправить, чтобы заставить пользователя отправлять параметры имени пользователя / пароля в каждом запросе и впоследствии проверять его по API-интерфейсу членства?

1 Ответ

0 голосов
/ 30 августа 2011

Чтобы ответить на ваш вопрос, ваше свойство UriTemplate пустое, поэтому возникает исключение. Он должен быть установлен следующим образом:

UriTemplate = "&username={username}&password={password}"

В вашем коде по-прежнему есть ошибка, поскольку оба входных параметра получают одну и ту же строку, а именно: username = JohnDoe: password = qwerty

Чтобы решить вашу проблему, это хорошая статья о том, как реализовать базовую аутентификацию HTTP с помощью веб-API WCF.

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