使用EF的C#Web Api无法调用方法

时间:2013-03-14 15:49:20

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

我用一些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 }
        ); 

我想知道为什么以前的方法不能一起工作(第一个和第二个)以及如果可能的话我可以做些什么来使它工作。我很确定它有什么东西,因为没有能够创建类似的方法似乎有点奇怪。

3 个答案:

答案 0 :(得分:3)

因为Web API只查找方法是" GET"并寻找一个" get"方法名称中的单词。因为你的方法都有"得到"并且两者都接受单个字符串参数,控制器可能正在解析它找到的第一个,并且因为" id"是使用GetUser方法返回的默认路由的一部分。

您还可以尝试为"用户名":

添加路线
config.Routes.MapHttpRoute(
        name: "ActionApi",
        routeTemplate: "api/{controller}/{username}",
        defaults: new { username = RouteParameter.Optional }
    ); 

编辑:尝试查看这些文章,了解路由如何与Web API配合使用。它与常规MVC控制器不同。

http://www.asp.net/web-api/overview/web-api-routing-and-actions

答案 1 :(得分:0)

此:

var user = db.Users.First(s => s.Username == id);
如果找不到具有该id的用户,

将导致异常

但是这个:

此:

var user = db.Users.FirstOrDefault(s => s.Username == id);

将返回null

答案 2 :(得分:0)

通过在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/2localhost:xxxxx/api/xxx/username/bob,这使得两个GET方法都可以工作,因为第二个路由规则接受了一个动作。

@Rob,感谢链接和提示,但感谢!