Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有EF的C#WebApi无法调用方法_C#_Entity Framework_Asp.net Mvc 4_Asp.net Web Api - Fatal编程技术网

带有EF的C#WebApi无法调用方法

带有EF的C#WebApi无法调用方法,c#,entity-framework,asp.net-mvc-4,asp.net-web-api,C#,Entity Framework,Asp.net Mvc 4,Asp.net Web Api,我已经用一些POCO类创建了一个MVC4WebAPI应用程序,并使用EF创建了一个具有读/写等功能的快速默认控制器 现在由于某种原因,我不能让这两个方法一起工作,但是第一个是EF创建的。简而言之,我想通过Id和用户名查找用户 // GET api/xxx public User GetUser(string id) { User user = db.Users.Find(id); if (user == null) {

我已经用一些POCO类创建了一个MVC4WebAPI应用程序,并使用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 }
        ); 
我想知道为什么前面的方法不能一起工作(第一个和第二个),如果可能的话,我可以做些什么使它工作。我很确定这其中有点道理,因为如果不能创建类似的方法,似乎有点奇怪。

这是:

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

但这是:

这:


将返回
null

因为Web API只查找方法为“GET”的事实,并在方法名称中查找“GET”字。由于您的两个方法都有“get”,并且都接受一个字符串参数,控制器可能正在解析为它找到的第一个参数,并且由于“id”是默认路由的一部分,它将与您的GetUser方法一起返回

您还可以尝试为“用户名”添加路由:

编辑:试着看看这些文章,看看路由如何与Web API一起工作。它与常规MVC控制器不同


在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;
}
我想我试得太多了,太傻了,但现在看来很清楚了

通过在routeTemplate中应用
{action}
的位置添加一个新路由是有意义的,因为这样我就可以添加一个属性
[ActionName(“username”)]
。然后我可以浏览
localhost:xxxxx/api/xxx/2
localhost:xxxxx/api/xxx/username/bob
,这使两个GET方法都能工作,因为第二个路由规则接受一个操作


@罗布,谢谢你的链接和提示,谢谢

如果您尝试类似localhost:xxxxx/api/xxx/4564(没有4564用户)的操作,您将面临一个InternalServerError。
// 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;
}