2011-12-09 135 views
4

我有一个ASP.NET MVC 3应用程序。我正试图实现在http://www.slideshare.net/calamitas/restful-best-practices找到的路由标准。我使用幻灯片15和17作为参考。我明白这个幻灯片是关于RAILS的。但是,这个语法似乎更清晰和更自然。这就是为什么我想要使用它。ASP.NET MVC 3和宁静的路由

我已经成功地实现了指数,并显示在我的控制器动作。但是,我在使“创建”和“更新”操作起作用时遇到问题。在这个时候,当我可以引用这些,我收到了404。目前,我的控制器看起来是这样的:

public class OrdersController : Controller 
{ 
    // GET: /Orders/ 
    public ActionResult Index() 
    { 
     var results = new[] { 
      new {id=1, price=1.23, quantity=2} 
     }; 
     return Json(results, JsonRequestBehavior.AllowGet); 
    } 

    // 
    // GET: /Orders/{orderID} 
    public ActionResult Show(int id) 
    { 
     string result = "order:" + id; 
     return Json(result, JsonRequestBehavior.AllowGet); 
    } 

    // 
    // POST: /Orders/{order} 
    [HttpPost] 
    public ActionResult Create(object order) 
    { 
     var message = "The order was successfully created!"; 
     return Json(message); 
    } 

    // 
    // PUT: /Orders/{orderID} 
    [HttpPut] 
    public ActionResult Update(object orderID) 
    { 
     var message = "The order was successfully updated!"; 
     return Json(message); 
    } 
} 

当我登记我的路线,我用的是以下几点:

context.MapRoute(
    "OrderList", 
    "Orders", 
    new { action = "Index", controller="Orders" } 
); 

context.MapRoute(
    "Order", 
    "Orders/{id}", 
    new { action = "Show", controller = "Orders", id="" } 
); 

context.MapRoute(
    "InsertOrder", 
    "Orders", 
    new { action = "Create", controller = "Orders" } 
); 

context.MapRoute(
    "UpdateOrder", 
    "Orders/{orderID}", 
    new { action = "Update", controller = "Orders", orderID = "" } 
); 

我试图通过JQuery创建和更新。当我使用以下内容时:

// Update 
var order = getOrder(); 
$.ajax({ 
    url: "/orders", 
    type: "put", 
    data: JSON.stringify(order), 
    contentType: "application/json", 
    success: function (result) { 
     alert(result); 
    }, 
    error: function() { 
     alert("There was a problem."); 
    } 
}); 


// Create 
var order = getOrder(); 
$.ajax({ 
    url: "/orders", 
    type: "post", 
    data: JSON.stringify(order), 
    contentType: "application/json", 
    success: function (result) { 
     alert(result); 
    }, 
    error: function() { 
     alert("There was a problem."); 
    } 
}); 

我在做什么错?因为它是一个404,我倾向于认为这是一个不正确的路由。我认为可能会有冲突,但我不知道如何证明或纠正这一点。同时,我不确定我是否在我的jQuery中正确设置数据属性。感谢您提供任何帮助。

+4

为什么你的两个路由具有相同的网址是什么? –

回答

2

您的网址缺少创建行动。将URL更改为以下内容:

$.ajax({ 
    url: "/orders/create", 
    .... 

原因是您的路由从未达到为订单定义的第二个路由。所有以订单开始的网址都将转到订单控制器和索引操作。

context.MapRoute( 
    "OrderList", 
    "Orders", 
    new { action = "Index", controller="Orders" } 
); 

编辑:

你应该在这种情况下使用一般的路由:

context.MapRoute( 
    "Order", 
    "Orders/{action}/{id}", 
    new { action = "Index", controller = "Orders", id="" } 
); 

如果URL是 '/订单',那么它会去 '指数',而是“/订单/创建'将进入控制器中的'创建'操作。

+0

但在URL我把它说,像一个URL“/订单/创建”不会是RESTful的。相反,主要的区别在于使用的Http Verb。我离开基地吗?或者,ASP.NET MVC无法做到这一点吗? –

+0

您必须将所有方法命名为“Index”并且有不同的重载,或者您需要有一个名为Index的方法,并在方法内部根据动词做不同的逻辑。 –

2

我想你只需要在下MapRoutes:

routes.MapRoute(
    "OrdersIndex", // Route name 
    "{controller}", // URL with parameters 
    new { 
      controller = "Orders", 
      action = "Index" 
     } // Parameter defaults 
); 
routes.MapRoute(
    "OrdersCrud", // Route name 
    "{controller}/{id}", // URL with parameters 
    new { 
      controller = "Orders", 
      action = "Crud" 
     } // Parameter defaults 
); 

然后在您的控制器类,你需要这样的事:

public class OrdersController : Controller 
{ 
    // GET: /Orders/ 
    [HttpGet] //GET is by default 
    public ActionResult Index() 
    { 
     var results = new[] { 
      new {id=1, price=1.23, quantity=2} 
     }; 
     return Json(results, JsonRequestBehavior.AllowGet); 
    } 
    // 
    // POST: /Orders/ 
    [HttpPost] 
    public ActionResult Index(object order) 
    { //Create 
     var message = "The order was successfully created!"; 
     return Json(message); 
    } 

    // 
    // GET: /Orders/{orderID} 
    [HttpGet]//GET is by default 
    public ActionResult Crud(int id) 
    { //Show 
     string result = "order:" + id; 
     return Json(result, JsonRequestBehavior.AllowGet); 
    } 

    // 
    // PUT: /Orders/{orderID} 
    [HttpPut] 
    public ActionResult Crud(object orderWithIDProperty) 
    { //Update 
     var message = "The order was successfully updated!"; 
     return Json(message); 
    } 

    // 
    // DELETE: /Orders/{orderID} 
    [HttpDelete] 
    public ActionResult Crud(int id) 
    { //Delete 
     var message = "The order was successfully deleted!"; 
     return Json(message); 
    } 
} 

请注意,您无需显式指定的[HttpGet]属性如本link解释。

+0

这是在正确的轨道上,但尚未完全。当您发布信息时,您将发布到列表中,而不是特定的ID,这是击中Crud动作的唯一方法。所以你需要改变crud动作的名字索引。另外,当您尝试在CRUD环境中工作时,您需要为每个操作指定允许的http方法。 –

+0

@NickLarsen你是对的。我更新了我的答案,把'HttpPost'索引(我可以用输入参数重载actionresult)'HttpDelete'。 – Galled