我正在尝试创建一个用于登录的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;
}
}
上图返回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 }
);
}
答案 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,这将自动映射为您。