Как передать специальные символы, чтобы 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" в моем браузере.

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