我无法访问我的ApiController

时间:2014-01-06 18:49:47

标签: c# asp.net-mvc asp.net-web-api

我正在尝试创建一个用于登录的Api控制器,应该在使用我的CustomerController(Api)访问数据之前使用。

问题是当我尝试在AccountController上访问我的Login方法时出现404错误。我正在尝试发布到AccountController,如下面的屏幕截图所示。

有趣的是,通过将浏览器指向CustomerController,我可以毫无问题地访问我的http://localhost:62655/api/customer/cvr/88888888(Api)。 我是否错过了POST请求的约定或其他内容?

我的WebApi路由配置是:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();

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

并添加到我的Global.asax:

WebApiConfig.Register(GlobalConfiguration.Configuration);

我的AccountController和CustomerController看起来像这样(文件合并为了简洁):

public class AccountController : ApiController
{
    public UserManager<ApplicationUser> UserManager { get; private set; }
    private IAuthenticationManager AuthenticationManager
    {
        get
        {
            return HttpContext.Current.GetOwinContext().Authentication;
        }
    }

    public AccountController(UserManager<ApplicationUser> userManager)
    {
        UserManager = userManager;
    }

    public async Task<HttpResponseMessage> Login([FromBody]LoginApiViewModel model)
    {
        if (!ModelState.IsValid) return Request.CreateResponse(HttpStatusCode.BadRequest, "Username or password is not supplied");

        var user = UserManager.Find(model.Username, model.Password);
        if (user != null && UserManager.IsInRole(user.Id, "Administrator"))
        {
            var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
            AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = true }, identity);

            var response = Request.CreateResponse(HttpStatusCode.OK, "Success");
            return response;
        }

        return Request.CreateResponse(HttpStatusCode.Unauthorized, "Wrong login");
    }
}

[Authorize(Roles = "Administrator")]
public class CustomerController : ApiController
{
    private readonly ICustomerService _customerService;

    public CustomerController(ICustomerService customerService)
    {
        _customerService = customerService;
    }

    [ActionName("cvr")]
    public CustomerApiViewModel GetCustomerById(string id)
    {
       var customer = _customerService.GetByCVR(id);
       if (customer == null) throw new HttpResponseException(HttpStatusCode.NotFound);
       var customerViewModel = Mapper.Map<CustomerApiViewModel>(customer);

       return customerViewModel;
    }
}

enter image description here

上图返回404错误。该计划是Fiddler2。

例外:

  

[HttpException]:路径'/ api / account / login'的控制器   未找到或未实现IController。

根据评论,更新 - (完成Global.asax和RouteConfig(MVC)

 protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    GlobalConfiguration.Configure(WebApiConfig.Register);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    AutoMapperWebConfiguration.Configure();

    GlobalConfiguration.Configuration.EnsureInitialized(); 
}

public static void RegisterRoutes(RouteCollection routes)
{
    routes.LowercaseUrls = true;
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "DefaultOnlyAction",
        "{action}",
        new { controller = "Home", action = "Index" }
    );

    routes.MapRoute(
        "Default",
        "{controller}/{action}/{id}",
        new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

4 个答案:

答案 0 :(得分:24)

将您的配置更改为如下所示...此处我在MVC路由之前移动了web api路由...这是因为Web API路由比通用MVC路由更具体..

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    GlobalConfiguration.Configure(WebApiConfig.Register);

    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

    RouteConfig.RegisterRoutes(RouteTable.Routes);

    BundleConfig.RegisterBundles(BundleTable.Bundles);

    AutoMapperWebConfiguration.Configure();
}

答案 1 :(得分:1)

这是因为你没有定义控制器的动作是[HttpGet]还是[HttpPost]。在您的情况下,您的登录操作应该是这样的

[HttpPost]
public async Task<HttpResponseMessage> Login([FromBody]LoginApiViewModel model)
{
    if (!ModelState.IsValid) return Request.CreateResponse(HttpStatusCode.BadRequest, "Username or password is not supplied");

    var user = UserManager.Find(model.Username, model.Password);
    if (user != null && UserManager.IsInRole(user.Id, "Administrator"))
    {
        var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
        AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = true }, identity);

        var response = Request.CreateResponse(HttpStatusCode.OK, "Success");
        return response;
    }

    return Request.CreateResponse(HttpStatusCode.Unauthorized, "Wrong login");
}

此外,您还需要为您的CVR行动提供[HttpGet]

答案 2 :(得分:1)

在您的Api类中使用路线表示法     〔路线(&#34; API / [控制器]&#34)]     public class WebApiController:ApiController     {

    // GET api/values
    [HttpGet]
    [Route("api/webapi")] //ROUTE <-- Work for me
    public IEnumerable<ProductViewData> Get()
    {
        //CODE
    }

    // POST api/values
    [HttpPost]
    [Route("api/webapi/save")] //ROUTE <-- Work for me
    public IHttpActionResult Post(ProductViewData product)
    {
        //CODE
    }
}

在你的Global.asax中:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}

在WebApiConfig.cs中:

public static void Register(HttpConfiguration config)
{
    config.MapHttpAttributeRoutes();

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

    //FOR User JSON format
    config.Formatters.Remove(config.Formatters.XmlFormatter);
    config.Formatters.JsonFormatter.SupportedMediaTypes.Add(
        new MediaTypeHeaderValue("application/json")
    );
}

答案 3 :(得分:0)

Web API方法以其类型开头,例如重命名方法postcvr,这将自动映射为您。

documentation link