PostAsJsonAsync не может найти запрошенный URI

В настоящее время я учусь создавать сервер C# с OWIN и Katana.

Я пытаюсь ответить на POST, но, к сожалению, он не находит функцию.

Итак, вот что у меня есть:

Это класс на стороне пользователя, который отправляет данные пользователя (имя пользователя и пароль) через POST (PostAsJsonAsync ()).

public class UserRegisterClient
{
    string _accessToken;
    Uri _baseRequestUri; // http://localhost:8080
    public UserRegisterClient(Uri baseUri, string accessToken)
    {
        _accessToken = accessToken;
        _baseRequestUri = new Uri(baseUri, "api/register/");
    }

    // Handy helper method to set the access token for each request:
    void SetClientAuthentication(HttpClient client)
    {
        client.DefaultRequestHeaders.Authorization
            = new AuthenticationHeaderValue("Bearer", _accessToken);
    }

    public async Task<HttpStatusCode> AddUserAsync(string username, string password)
    {
        HttpResponseMessage response;
        using (var client = new HttpClient())
        {
            SetClientAuthentication(client);
            response = await client.PostAsJsonAsync(
                _baseRequestUri.ToString(), new KeyValuePair<string, string>(username, password));
        }
        return response.StatusCode;
    }
}

Дополнительная информация:
в функции AddUserAsync client.PostAsJsonAsync() возвращает следующее:

response =  
{
    StatusCode: 404,
    ReasonPhrase: 'Not Found',
    Version: 1.1,
    Content: System.Net.Http.StreamContent,
    Headers: 
    {   
        Date: Sat, 11 Jul 2015
        18:16:53 GMT   Server: Microsoft-HTTPAPI/2.0   Content-Length: 190  
        Content-Type: application/json; charset=utf-8
    }
}   System.Net.Http.HttpResponseMessage


На стороне сервера у меня есть контроллер, который выглядит так:

[RoutePrefix("api/register/")]
class RegisterController : ApiController
{
    public async Task<IHttpActionResult> Post(KeyValuePair<string, string> userData) 
    {
       // I never get inside here
    }
}

На стороне сервера в классе Startup вы можете увидеть настройки маршрута:

private HttpConfiguration ConfigureWebApi()
{
      var config = new HttpConfiguration();
      config.Routes.MapHttpRoute(
           "DefaultApi",
           "api/{controller}/{id}",
           new { id = RouteParameter.Optional });
      return config;
}

Изменить: изменил Route на RoutePrefix до моего класса контроллера.

3 ответа

Решение

Сделайте класс Controller общедоступным.

[Route("api/register/")]
public class RegisterController : ApiController

Отсутствие общедоступности означает, что система Web API не может обнаружить контроллер и его действия.

Первое, на что я бы обратил внимание, - это какие пакеты NuGet вы установили и убедитесь, что в вашем классе Startup все хорошо. Ваш класс запуска должен выглядеть так:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = ConfigureWebApi();
        app.UseWebApi(config);
    }
}

Убедитесь, что у вас установлены эти пакеты NuGet, если вы размещаете на IIS:

  • Newtonsoft.Json
  • Microsoft.AspNet.WebApi.Client
  • Microsoft.AspNet.WebApi.Core
  • Microsoft.AspNet.WebApi.Owin
  • Microsoft.Owin.Host.System.Web
  • Microsoft.Owin
  • Owin

Попробуй добавить public на ваш контроллер:

[Route("api/register/")]
public class RegisterController : ApiController
{
    public async Task<IHttpActionResult> Post(KeyValuePair<string, string> userData) 
    {
       // I never get inside here
    }
}

Поскольку вы используете owin/katana и маршрутизацию атрибутов, вы можете избавиться от конфигурации веб-API старого стиля:

var config = new HttpConfiguration();
      config.Routes.MapHttpRoute(
           "DefaultApi",
           "api/{controller}/{id}",
           new { id = RouteParameter.Optional });
      return config;

и используя это вместо этого:

config.MapHttpAttributeRoutes();

до

app.UseWebApi(config);

Делая это, вы должны будете префикс каждого рутирования в вашем веб-API, но, я думаю, это легче понять, и я слышал, что это станет стандартом с vNext.

Другие вопросы по тегам