Как передать специальные символы, чтобы ASP.NET MVC мог корректно обрабатывать строковые данные запроса?
Я использую маршрут, подобный этому:
routes.MapRoute("Invoice-New-NewCustomer",
"Invoice/New/Customer/New/{*name}",
new { controller = "Customer", action = "NewInvoice" },
new { name = @"[^\.]*" });
Есть действие, которое обрабатывает этот маршрут:
public ActionResult NewInvoice(string name)
{
AddClientSideValidation();
CustomerViewData viewData = GetNewViewData();
viewData.InvoiceId = "0";
viewData.Customer.Name = name;
return View("New", viewData);
}
Когда я вызываю return RedirectToAction("NewInvoice", "Customer", new {name});
, а имя равно "С# Guy", параметр "name" усекается до "The C".
Итак, мой вопрос: какой лучший способ обработать этот особый символ с помощью ASP.NET MVC?
Спасибо!
Ответы
Ответ 1
Хорошо, я подтвердил, что это уже известная проблема в ASP.NET Routing, к сожалению. Проблема в том, что в глубине неровностей маршрутизации мы используем Uri.EscapeString при выходе из параметров маршрутизации для Uri. Однако этот метод не пропускает символ "#".
Обратите внимание, что символ # (aka Octothorpe) является технически неправильным символом. C♯ язык на самом деле является "C", за которым следует знак Sharp, как в музыке: http://en.wikipedia.org/wiki/Sharp_(music)
Если вы использовали резкий знак, который потенциально может решить эту проблему.: P
Другое решение, так как большинство людей захотят использовать octothorpe, это написать собственный маршрут для этого маршрута и после получения пути виртуального пути закодировать знак #, используя HttpUtility.UrlEncode, который кодирует # до% 23.
В качестве продолжения я хотел указать вам на это сообщение в блоге, в котором говорится о передаче других "недопустимых" символов. http://haacked.com/archive/2010/04/29/allowing-reserved-filenames-in-URLs.aspx
Ответ 2
Кодирование URL! Измените ссылку так, чтобы она кодировала специальные символы.
Server.URLencode(strURL)
С# станет "c% 23".
Ответ 3
Работает на моей машине. Вот что я сделал, чтобы создать простейший возможный пример.
//Global.asax.cs
using System.Web.Mvc;
using System.Web.Routing;
namespace MvcApplication4 {
public class MvcApplication : System.Web.HttpApplication {
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
routes.MapRoute("Invoice-New-NewCustomer",
"Invoice/New/Customer/New/{*name}",
new { controller = "Customer", action = "NewInvoice" },
new { name = @"[^\.]*" });
}
protected void Application_Start() {
RegisterRoutes(RouteTable.Routes);
}
}
}
//HomeController.cs
using System.Web.Mvc;
namespace MvcApplication4.Controllers {
[HandleError]
public class HomeController : Controller {
public ActionResult Index() {
return RedirectToAction("NewInvoice", "Customer", new { name = "The C# Guy" });
}
}
}
//CustomerController.cs
using System.Web.Mvc;
namespace MvcApplication4.Controllers {
public class CustomerController : Controller {
public string NewInvoice(string name) {
return name;
}
}
}
Затем я начал свое приложение и перешел в /home/index. Переадресация происходит, и я видел "С# Guy" в моем браузере.