Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.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
Asp.net mvc Web API(独立)和Web API ASP.NET MVC之间的区别_Asp.net Mvc_Asp.net Web Api - Fatal编程技术网

Asp.net mvc Web API(独立)和Web API ASP.NET MVC之间的区别

Asp.net mvc Web API(独立)和Web API ASP.NET MVC之间的区别,asp.net-mvc,asp.net-web-api,Asp.net Mvc,Asp.net Web Api,我创建了一个ASP.NET MVC项目,其中包括Web API,我还创建了一个空项目,其中只选择了Web API,我试图理解为什么它们的行为不同 据我所知,这两种类型的路由定义如下所示: config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = R

我创建了一个
ASP.NET MVC
项目,其中包括
Web API
,我还创建了一个空项目,其中只选择了
Web API
,我试图理解为什么它们的行为不同

据我所知,这两种类型的路由定义如下所示:

config.MapHttpAttributeRoutes();

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);
但我想理解为什么控制器中定义的函数表现不同

在我的
ASP.NET MVC
解决方案中,我可以在一个控制器下创建多个函数:

public IEnumerable<Product> GetAllProducts()
{
    return products;
}

public IHttpActionResult GetProduct(int id)
{
    var product = products.FirstOrDefault((p) => p.Id == id);
    if (product == null)
    {
        return NotFound();
    }
    return Ok(product);
}
但是,除非我将
[HttpGet]
属性添加到HelloWorld函数中,否则上述操作将不起作用

此外,我似乎无法在一个控制器中定义多个函数,因为它是在
ASP.NET MVC
解决方案中完成的。定义与上面相同的函数是行不通的,或者即使我定义了下面的函数也是行不通的

[HttpGet]
public IHttpActionResult HelloWorld()
{
    return Ok("Hello World");
}

[HttpGet]
public IHttpActionResult GetTime()
{
    return Ok(DateTime.Now.ToString());
}
我得到以下错误:

<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
    Multiple actions were found that match the request: HelloWorld on type 
    MyProject.Controllers.TestController GetTime on type 
    MyProject.Controllers.TestController
</ExceptionMessage>
<ExceptionType>System.InvalidOperationException</ExceptionType>
<StackTrace>
    at 
    System.Web.Http.Controllers.ApiControllerActionSelector.
    ActionSelectorCacheItem.SelectAction(HttpControllerContext 
    controllerContext) at System.Web.Http.ApiController.
    ExecuteAsync(HttpControllerContext controllerContext, CancellationToken 
    cancellationToken) at System.Web.Http.Dispatcher.
    HttpControllerDispatcher.<SendAsync>d__15.MoveNext()
</StackTrace>

发生了一个错误。
找到多个与请求匹配的操作:类型为的HelloWorld
类型上的MyProject.Controllers.TestController GetTime
MyProject.Controllers.TestController
System.InvalidOperationException异常
在
System.Web.Http.Controllers.ApiControllerActionSelector。
ActionSelectorCacheItem.SelectAction(HttpControllerContext
controllerContext),位于System.Web.Http.ApiController。
ExecuteAsync(HttpControllerContext controllerContext,CancellationToken
在System.Web.Http.Dispatcher上的cancellationToken)。
HttpControllerDispatcher.d_u15.MoveNext()

当我定义单个函数时,当我调用下面的

它似乎并不关心调用什么函数名,因为如果我调用以下任何一个函数,它都会工作:

并且仅当我提供无效的控制器名称时才会失败,即

你能解释一下2和理想情况之间的区别吗?我需要做什么才能使一个独立的Web API与在
Asp.net MVC

谢谢

更新-1

下面是两个行为明显不同的好例子,但我不明白为什么两者都被称为“带ASP.NET MVC的Web API”

编辑:

我很抱歉,一开始我误解了你的询问,因此给了你错误的答案

在WebAPI中,不能定义两个服务于完全相同路径的函数。但是您可以像使用函数一样重载它们

public IEnumerable<Product> GetAllProducts() {}
public IHttpActionResult GetProduct(int id) {}
另一方面,以下函数都为
localhost/api/test/

[HttpGet]
public IHttpActionResult HelloWorld()
{
    return Ok("Hello World");
}

[HttpGet]
public IHttpActionResult GetTime()
{
    return Ok(DateTime.Now.ToString());
}
第二个问题是命名,以及为什么没有
[HttpGet]
就无法定义
HelloWorld()
。这是因为WebAPI会自动将名称中包含关键字(如Get或Delete)的函数映射到相应的Http函数

仅当函数名不符合这些命名约定或应服务于多个Http方法时,才需要添加Http属性。它被描述了

我希望你的问题现在得到回答

来源:

MVC和WebAPI之间的默认路由和后续执行什么函数的决定是不同的

默认Web Api:

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

config.Routes.MapHttpRoute(
    name: "DefaultMvc",
    routeTemplate: "/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);
对于Web Api而言,路由取决于控制器名称、选择的Http方法以及实际具有此方法标记的功能的控制器。因此,需要添加和进一步添加标签

Mvc另一方面,通过控制器名称和操作名称路由到所需的功能


WebAPI2进一步增加了允许您定义属性输出的可能性。您可能想进一步了解这个主题,可能是,但我刚刚提供了两个链接,突出了我的问题,因为这两个链接都被称为
ASP.NET MVC Web API
,但它们的定义和行为不同,这正是我试图理解的,希望能够提供一个解决方案,以解决如何使它的行为与在ASP.NET MVC Web应用程序中定义的行为相同。我的独立Web api项目和ASP.NET MVC Web应用程序(其中选择了Web api)都包含您在回答中提供的
默认Web api
,但希望您提供的链接会有所帮助。谢谢你会在不同的文件中找到不同的路径。MVC在RouteConfig.cs中,API在WebApiConfig.cs中。这样,您就可以在解决方案中为控制器和Api控制器定义不同的路由行为这两个项目都已经有了WebApiConfig.cs,其中定义了“默认web Api”映射。如果您查看我提供的两个链接,它几乎是一样的。两者都是在WebApiConfig.cs中定义的,都继承自ApicController,但它们的行为不同。感谢您的详细说明。我目前正在阅读您提供的链接,但我仍然不清楚GetAllProducts()和GetProduct()是如何在Microsoft示例中定义的,而不是在我的项目中定义的。我在家里创建了一个新项目,其中我的控制器名为“DocumentController”,它继承自ApiController,它有一个名为GetById(int id)的函数,但如果我调用它,它就不起作用,但如果我调用它,它会起作用。我知道api不包含操作,但它是否包含在Microsoft示例中?谢谢
config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);    
config.Routes.MapHttpRoute(
    name: "DefaultMvc",
    routeTemplate: "/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);