Как передать специальные символы, чтобы 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});
и имя равно "C# Guy", параметр "имя" усекается до "C".
Итак, мой вопрос: как лучше всего обрабатывать такого рода специальные символы в ASP.NET MVC?
Спасибо!
3 ответа
Хорошо, я подтвердил, что это, к сожалению, известная проблема в ASP.NET Routing. Проблема в том, что глубоко в недрах маршрутизации мы используем Uri.EscapeString при экранировании параметров маршрутизации для Uri. Однако этот метод не экранирует символ "#".
Обратите внимание, что символ # (он же Octothorpe) является технически неправильным символом. C♯ язык на самом деле является буквой "C", за которой следует знак "Sharp", как в музыке: http://en.wikipedia.org/wiki/Sharp_(music)
Если вы использовали острый знак, это может решить эту проблему.:П
Другое решение, так как большинство людей захотят использовать octothorpe, это написать собственный маршрут для этого маршрута и после получения пути виртуального пути закодировать знак #, используя HttpUtility.UrlEncode, который кодирует # в%23.
В качестве продолжения я хотел бы указать вам на этот пост в блоге, в котором говорится о передаче других "недопустимых" персонажей. http://haacked.com/archive/2010/04/29/allowing-reserved-filenames-in-URLs.aspx
Кодировка URL! Измените ссылку, чтобы она кодировала специальные символы.
Server.URLencode(strURL)
C# станет "c%23".
Работает на моей машине. Вот что я сделал, чтобы создать самый простой пример.
//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. Переадресация происходит, и я увидел "C# Guy" в моем браузере.