2

首次设置Web API,所以可能很愚蠢的问题。我开始使用无身份验证的API,然后通过基本上从标准项目复制来添加OAuth身份验证。现在在API上注册操作给出“没有发现HTTP资源[...]”

,我面临的挑战是,当我尝试使用邮差创建一个帐户,我得到:

{ 
    "Message": "No HTTP resource was found that matches the request URI 'http://api.asanoapp.com/api/Account/Register'.", 
    "MessageDetail": "No action was found on the controller 'Account' that matches the request." 
} 

我做的是我发表的帖子中我的下面(截图调用邮差:http://prntscr.com/gch0j9):

http://api.domain.com/api/Account/Register 

用下面的身体(生):

{ 
    "Email": "[email protected]", 
    "Password": "1234pass", 
    "ConfirmPassword": "1234pass" 
} 

AccountController这是从一个标准的项目复制,具有以下声明:

[Authorize] 
[RoutePrefix("api/Account")] 
public class AccountController : ApiController 
{ 
    private const string LocalLoginProvider = "Local"; 
    private ApplicationUserManager _userManager; 

    // 400+ lines of more standard stuff 
} 

Register方法是这样的:

// POST api/Account/Register 
[AllowAnonymous] 
[Route("Register")] 
public async Task<IHttpActionResult> Register(RegisterBindingModel model) 
{ 
    if (!ModelState.IsValid) 
    { 
     return BadRequest(ModelState); 
    } 

    var user = new ApplicationUser() { UserName = model.Email, Email = model.Email }; 

    IdentityResult result = await UserManager.CreateAsync(user, model.Password); 

    if (!result.Succeeded) 
    { 
     return GetErrorResult(result); 
    } 

    return Ok(); 
} 

现在,我不明白为什么我得到的"No action was found on the controller",因为我都有这种方法,我打电话给正确的主体(RegisterBindingModel从默认项目viewmodel)。

我在这里错过了什么?

编辑:

WebApiConfig:

public static void Register(HttpConfiguration config) 
     { 
      // Web API configuration and services 
      // Configure Web API to use only bearer token authentication. 
      config.SuppressDefaultHostAuthentication(); 
      config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); 
      // Web API routes 
      config.MapHttpAttributeRoutes(); 

      config.Routes.MapHttpRoute(
       name: "DefaultApi", 
       routeTemplate: "api/{controller}/{id}", 
       defaults: new {id = RouteParameter.Optional}); 

      config.Formatters.JsonFormatter.SupportedMediaTypes 
       .Add(new MediaTypeHeaderValue("text/html")); 

     } 

Startup.cs:

[assembly: OwinStartup(typeof(Asano.Websites.Api.Startup))] 

namespace Asano.Websites.Api 
{ 
    public partial class Startup 
    { 
     public void Configuration(IAppBuilder app) 
     { 
      ConfigureAuth(app); 
     } 
    } 
} 

Startup.Auth(其中ConfigureAuth是):

public partial class Startup 
    { 
     public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; } 

     public static string PublicClientId { get; private set; } 

     // For more information on configuring authentication, please visit https://go.microsoft.com/fwlink/?LinkId=301864 
     public void ConfigureAuth(IAppBuilder app) 
     { 
      // Configure the db context and user manager to use a single instance per request 
      app.CreatePerOwinContext(AsanoWebsitesApiContext.Create); 
      app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); 

      // Enable the application to use a cookie to store information for the signed in user 
      // and to use a cookie to temporarily store information about a user logging in with a third party login provider 
      app.UseCookieAuthentication(new CookieAuthenticationOptions()); 
      app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); 

      // Configure the application for OAuth based flow 
      PublicClientId = "self"; 
      OAuthOptions = new OAuthAuthorizationServerOptions 
      { 
       TokenEndpointPath = new PathString("/Token"), 
       Provider = new ApplicationOAuthProvider(PublicClientId), 
       AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"), 
       AccessTokenExpireTimeSpan = TimeSpan.FromDays(14), 
       // In production mode set AllowInsecureHttp = false 
       AllowInsecureHttp = true 
      }; 

      // Enable the application to use bearer tokens to authenticate users 
      app.UseOAuthBearerTokens(OAuthOptions); 

      // Uncomment the following lines to enable logging in with third party login providers 
      //app.UseMicrosoftAccountAuthentication(
      // clientId: "", 
      // clientSecret: ""); 

      //app.UseTwitterAuthentication(
      // consumerKey: "", 
      // consumerSecret: ""); 

      //app.UseFacebookAuthentication(
      // appId: "", 
      // appSecret: ""); 

      //app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions() 
      //{ 
      // ClientId = "", 
      // ClientSecret = "" 
      //}); 
     } 
    } 

的Global.asax.cs - 应用程序启动:

public class WebApiApplication : System.Web.HttpApplication 
    { 
     protected void Application_Start() 
     { 
      AreaRegistration.RegisterAllAreas(); 
      GlobalConfiguration.Configure(WebApiConfig.Register); 
      FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
      RouteConfig.RegisterRoutes(RouteTable.Routes); 
      BundleConfig.RegisterBundles(BundleTable.Bundles); 
     } 
    } 
+0

你可以尝试添加/更改邮递员中的Content-Type头,所以它的值是application/json而不是文本 – JConstantine

+0

我刚刚试过这个@JLevett - http://prntscr.com/gcjn4a。仍然找回没有发现的行动 –

+0

嗯 - 在这里拉伸,但也许该网址是区分大小写。在PM – JConstantine

回答

1

不幸的是,这篇文章的答案并没有帮助我找到一个可行的解决方案。因此,我做了以下的这一切:

添加以下属性我register方法:

[Route("api/account/register")] 

并将其加入后,它的工作原理。所以看起来底层的问题是控制器的前缀不起作用。

但是,做上面的事情工作(但显然是一个黑客)。

+0

虽然很奇怪。必须对此进行一些研究。我建议的代码在很多生产应用程序中都没有问题。奇怪的。 – Nkosi

1

你缺少的,它可以让路由表的动作[HttpPost]属性知道操作可以处理匹配的路由模板POST请求。

[Authorize] 
[RoutePrefix("api/Account")] 
public class AccountController : ApiController { 
    //...code removed for brevity 

    [HttpPost]//<-- this guy 
    [AllowAnonymous] 
    [Route("Register")] //Matches POST api/Account/Register 
    public async Task<IHttpActionResult> Register(RegisterBindingModel model) { 
     //...code removed for brevity 
    } 
} 
+0

虽然我很确定这也是一个问题,但这并没有解决我的挑战。你有任何其他的想法可能是什么? : -/ –

+0

@LarsHoldgaard自您使用属性路由以来的假设是您还启用了它。显示'WebApiConfig'并确保启用了属性路由'config.MapHttpAttributeRoutes();' – Nkosi

+0

我刚刚添加了它。它似乎在那里。其他任何有意义的外观? –

相关问题