带EF的c# WebApi不能调用方法
本文关键字:不能 调用 方法 WebApi EF | 更新日期: 2023-09-27 18:03:50
我创建了一个带有POCO类的MVC 4 WebApi应用程序,并使用EF创建了一个具有读/写等功能的快速默认控制器
现在由于某种原因,我不能让这两个方法一起工作,但是第一个是EF创建的。简而言之,我想通过Id和用户名找到用户。
// GET api/xxx
public User GetUser(string id)
{
User user = db.Users.Find(id);
if (user == null)
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
return user;
}
以上工作。
// GET api/xxx
public User GetUserByUsername(string username)
{
var user = db.Users.First(s => s.Username == username);
if (user == null)
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
return user;
}
但是通过将其更改为以下内容并在webapi配置中添加一些内容,然后以下工作:
// GET api/xxx
[HttpGet]
[ActionName("username")]
public User GetUserByUsername(string id)
{
var user = db.Users.First(s => s.Username == id);
if (user == null)
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
return user;
}
并将WebApiConfig更改为:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// Action-name
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
我想知道为什么以前的方法不能一起工作(第一个和第二个),如果可能的话,我能做些什么来使它工作。我很确定这是有原因的,因为不能创建类似的方法似乎有点奇怪。
因为Web API只查找方法是"GET"这一事实,并在方法名中查找一个"GET"字。因为你的两个方法都有"get"并且都接受单个字符串参数,控制器可能会解析到它找到的第一个,并且因为"id"是默认路由的一部分,它会与你的GetUser方法一起返回。
你也可以尝试为"username"添加一个路由:
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{username}",
defaults: new { username = RouteParameter.Optional }
);
EDIT:试着看看这些文章,看看路由如何与Web API一起工作。它与常规的MVC控制器不同。
http://www.asp.net/web-api/overview/web-api-routing-and-actionsThis:
var user = db.Users.First(s => s.Username == id);
如果没有找到具有该id的用户将导致异常
但这:
:
var user = db.Users.FirstOrDefault(s => s.Username == id);
将返回null
。
通过在DefaultApi之后添加新的路由规则使其工作,
// Routing by Action-name
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{username}",
defaults: new { username = RouteParameter.Optional }
);
并将方法更改为:
// GET api/xxx/username
[ActionName("username")]
public User GetUserByUsername(string username)
{
var user = db.Users.FirstOrDefault(s => s.Username == username);
if (user == null)
{
throw new HttpResponseException(
Request.CreateResponse(HttpStatusCode.NotFound));
}
return user;
}
我想我试得太多了,很傻,但现在看起来很清楚了。
通过添加一个新的路由,我将{action}
应用到routeTemplate是有意义的,因为我可以添加一个属性[ActionName("username")]
。然后我可以浏览localhost:xxxxx/api/xxx/2
和localhost:xxxxx/api/xxx/username/bob
,这使得两个GET方法都工作,因为第二个路由规则接受一个操作。