【问题标题】:Web API: different way of attribute routingWeb API:属性路由的不同方式
【发布时间】:2017-11-10 09:11:23
【问题描述】:

我正在学习 web api。刚刚浏览了几篇文章,发现属性路由可以通过不同的方式完成。

查看使用的代码:

[RoutePrefix("Movie")]
public class HomeController : Controller
{
      //Route: Movie/Index
      [Route]
      public ActionResult Index()
      {
           ViewBag.Message = "You are in Home Index";
           return View();
      }

      //Route: NewRoute/About
       [Route("~/NewRoute/About")]
       public ActionResult About()
       {
           ViewBag.Message = "You successfully reached NEWRoute/About route";
           return View();
       }
}

在上面的例子中作者使用 Route 属性来定义动作的路由。

再看一次

[GET("productid/{id?}")]
public HttpResponseMessage Get(int id)
{
    var product = _productServices.GetProductById(id);
    if (product != null)
        return Request.CreateResponse(HttpStatusCode.OK, product);
    return Request.CreateErrorResponse(HttpStatusCode.NotFound, "No product found for this id");
}

这里作者没有使用路由属性,而是使用http动词来定义路由。

那么告诉我哪种方法是正确的?

另一个问题是,我们可以通过属性例程为动作赋予不同的名称,那么何时应该使用动作名称属性为动作赋予不同的名称?

当我们可以通过属性路由更改动作名称时,为什么要使用动作名称属性为动作赋予不同的名称?

【问题讨论】:

  • 你也可以使用[HttpGet]属性来定义http动词。我使用它和 [Route()] 是因为我在路由中有操作方法名称,imo 提供了最好的可读性但确实很混乱。

标签: c# asp.net-web-api


【解决方案1】:

[Route] 向外界公开一个动作。它将动作名称(方法名称)作为路由的名称。它可以使用RoutePrefix 或控制器名称来构造URL。

如果您向[Route(template)] 提供值,则该(相对)URL 将用于构造操作可用的URL。

由于默认情况下只能通过GET 访问路由,因此您可以以相同的方式使用HttpGet(template)Route。例如,如果您将RouteHttpGetHttpPost 一起使用,则可以通过这些动词获得该路线。

因此,您可以根据自己的需要和偏好进行一些混合。

【讨论】:

  • 感谢您的回复,但很抱歉,我不明白您所说的 Since routes are by default only accessible through GET, you can use HttpGet(template) and Route the same way. If you use Route together with HttpGet and HttpPost for example, that route will be available through those verbs. 之类的内容,因此您可以举例说明您要说的内容,从而更清楚地说明这一点。谢谢
  • 我见过一些人使用多条路线进行相同的操作......什么时候应该遵循这些方法?只需检查此网址codeproject.com/Articles/1005485/…,您必须注意到多个路线已用于单个操作....为什么?
【解决方案2】:

我相信[Route]RoutePrefix 是帮助我们定义向客户端浏览器公开的 URL 的那些属性。

回答

帕特里克·霍夫曼 很好解释。

为了清楚地表明任何书面方法的工作原理,提供了HTTP 动词。最近,我开发了小型 Web API 解决方案,我尝试并测试了具有多个属性的路由场景。他们在这里:

[ActionName("GetIndex")]
[HttpGet]
public HttpResponseMessage IndexIdById(string id)
{
... other relative code here ...
var response = new HttpResponseMessage(HttpStatusCode.OK);
return response;
}

如果方法名没有任何Get 前缀(如上例所示) 它将给出精确的指示来指定[HttpGet] 动词以显示该方法正在做什么。这里这个方法是Get方法。

还有像上面这样的方法名,提供一个别名会更好。 [ActionName("GetIndex")]

为了通过路由配置来支持这种方法,我们可以提供将动作名称与WebApiConfig.cs 中的 URL 的其他部分映射的路由。示例如下:-

config.Routes.MapHttpRoute(
name: "GetIndex",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: null
);

感谢其他人对此答案的建议或改进。因为这个配置我的 Web API 的策略对我很有效。

【讨论】:

  • 感谢您的回复。告诉我此操作的网址是什么IndexIdById
  • localhost 上运行时,URL 应该是 :-。 localhost:[portnumber]/api/services/getindex/10000 其中反映了以下配置:- services = {controller} getindex = {action} - 这是我在操作 10000 = {id 上方设置为 [ActionName("GetIndex")] 的别名}
【解决方案3】:
routes.MapRoute(
  "DesktopLogin",
  "{controller}/account/Function1",
  new { controller = "My", action = "Login" }
 );
 routes.MapRoute(
"NewDeskTopLogin",
 "{controller}/account/Function1",
 new { controller = "My", action = "Login" }
 );

 ///////////RouteAttribute and HttpPost together on same action


[Route("DesktopLogin")]
public ActionResult Function1(LoginModel model)
{
  return View("~/Views/Account/Login.cshtml");
 }

[Route("NewDeskTopLogin")]
[HttpPost]
public ActionResult Function1(LoginModel model)
{
  return View("~/Views/Account/Login.cshtml");
}

【讨论】:

    猜你喜欢
    • 2017-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-22
    • 1970-01-01
    • 2017-08-16
    • 2013-11-11
    相关资源
    最近更新 更多