ASP.NET MVC 3 и спокойная маршрутизация

У меня есть приложение ASP.NET MVC 3. Я пытаюсь внедрить стандарт маршрутизации, который можно найти по адресу http://www.slideshare.net/calamitas/restful-best-practices. Я использую слайды 15 и 17 для справки. Я понимаю, что эта колода относится к рельсам. Однако этот синтаксис выглядит намного чище и естественнее. Вот почему я хочу использовать это.

Я успешно реализовал действия Index и Show в моем контроллере. Однако у меня возникли проблемы с выполнением действий "Создать" и "Обновить". В это время, когда я ссылаюсь на любой из них, я получаю 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. Спасибо за любую помощь, которая может быть оказана.

2 ответа

Решение

В вашем URL отсутствует действие для создания. Измените URL на следующий:

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

Причина в том, что ваш маршрут никогда не достигнет второго, определенного для заказов. Все URL, начинающиеся с Orders, перейдут к контроллеру 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" в контроллере.

Я думаю, что вам нужны только следующие 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] атрибут, как описано в этой ссылке.

Другие вопросы по тегам