【问题标题】:ASP.NET MVC 3 and restful routingASP.NET MVC 3 和 restful 路由
【发布时间】:2011-12-09 16:17:05
【问题描述】:

我有一个 ASP.NET MVC 3 应用程序。我正在尝试实现http://www.slideshare.net/calamitas/restful-best-practices 的路由标准。我使用幻灯片 15 和 17 作为参考。我知道这个幻灯片是关于 RAILS 的。但是,这种语法看起来更干净、更自然。这就是我想使用它的原因。

我已经在我的控制器中成功实现了 Index 和 Show 操作。但是,我无法让 Create 和 Update 操作正常工作。此时,当我引用其中任何一个时,我都会收到 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 中正确设置了 data 属性。感谢您提供的任何帮助。

【问题讨论】:

  • 为什么你的两条路线有相同的 url?

标签: jquery asp.net-mvc-3 asp.net-mvc-routing


【解决方案1】:

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

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

原因是您的路由永远不会到达为订单定义的第二个。所有以 Orders 开头的 url 都将转到 Order 控制器和 Index 操作。

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

编辑:

在这种情况下,您应该使用通用路由:

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

如果 URL 是“/Orders”,那么它将转到“Index”,但“/Orders/Create”将转到控制器中的“Create”操作。

【讨论】:

  • 但在我包含的 URL 中,它指出像“/Orders/Create”这样的 URL 不会是 RESTful。相反,主要区别在于使用的 Http 动词。我离基地很远吗?或者,是不是 ASP.NET MVC 不能做的事情?
  • 您必须将所有方法命名为“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 中所述。

【讨论】:

  • 这是在正确的轨道上,但还不是完全正确的。当您发布时,您是在发布到列表,而不是特定的 id,这是点击 Crud 操作的唯一方法。因此,您需要更改 crud 操作以具有名称索引。此外,当您尝试在 CRUD 环境中工作时,您需要为每个操作指定允许的 http 方法。
  • @NickLarsen 你是对的。我更新了我的答案,将HttpPost 索引(我可以使用输入参数重载actionresult)HttpDelete
猜你喜欢
  • 2011-08-11
  • 1970-01-01
  • 2010-12-12
  • 2011-08-31
  • 2011-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多