2012-02-19 2 views
0

Я управляю приложением MVC3, где мне нужно поддерживать способность третьих сторон создавать ссылку на активы в моем домене. Поскольку некоторые из звеньев нарезанные кубиками по слияниям почты и других проблем редактирования текста, URL с опечатками были введены, например:Использование маршрутов для исправления опечаток в URL-адресе

/Content/ima!+ges/email/spacer.gif 

или

/Content/image++s/email+/spacer.gif 

Я хотел бы, чтобы лишить их посторонними символов от RegEx, прежде чем пытаться их обслуживать. Я считаю, что это может быть метод Route, и я бы приветствовал указатель или два статьи, демонстрирующие этот подход.

ДОПОЛНЕНИЕ (Потому что мне нужно форматирование).

Реализация @ маршрутизации Натана я не могу отправить имя файла обработчика контроллера - это всегда видеть нулевое значение, передаваемое в Я пробовал как "filepath 'и' path 'с тем же результатом "null".

 routes.MapRoute(
      "MangledFilename", 
      "{*filepath}", 
      new { controller = "MangledFilename", action = "ServeFile" } 
     ); 

Я думаю, что это вопрос настройки обработки подстановочных знаков на IISExpress и я ищу это решение отдельно. Более серьезная немедленная проблема заключается в том, как ваше предложение возвращает HttpNotFound - я получаю жесткое исключение IIS (выполнение останавливается с помощью YellowScreenDeath) вместо результата без звука 404.

public ActionResult ServeFile(string filePath) 
    { 
     if (filePath != null) // workaround the null 
     { 
       ... 
     } 
     return HttpNotFound(); 
    } 

ТНХ

ответ

0

Я думаю, что что-то по этому подход должен работать:

Сначала добавьте маршрут, как это до конца ваших маршрутов регистрации деклараций:

routes.MapRoute(
     "MangledFilename", 
     "{*filepath}", 
     new { controller = "MangledFilename", action = "ServeFile" }); 

Если вы еще Прежде всего, параметр маршрута с * после открытия { является подстановочным параметром, в этом случае он будет соответствовать ire путь. Вы также можете написать его как content/{*filepath}, если вы хотите ограничить это поведение в своем каталоге content.

И тогда контроллер что-то вроде этого следует сделать трюк:

public class MangledFilenameController : Controller 
    { 
     public ActionResult ServeFile(string filePath) 
     { 
      filePath = CleanFilePath(filePath); 
      var absolutePath = Server.MapPath(filePath); 

      if (System.IO.File.Exists(absolutePath)) 
      { 
       var extension = System.IO.Path.GetExtension(absolutePath); 
       var contentType = GetContentTypeForExtenion(extension); 
       return File(absolutePath, contentType); 
      } 

      return HttpNotFound(); 
     } 

     private string CleanFilePath(string filepath) 
     { 
      //clean the path up 
      return filepath; 
     } 

     private string GetContentTypeForExtenion(string extension) 
     { 
      //you will want code here to map extensions to content types 
      return "image/gif"; 
     } 
    } 

В отношении отображения расширения к типу/содержимого MIME для метода GetContentTypeForExtension, вы можете выбрать для жестких типов коды вы ожидаете служить, или использовать одно из решений, описанных в этой статье:

File extensions and MIME Types in .NET

РЕДАКТИРОВАТЬ:

Подумав об этом, я понял, что есть еще один способ справиться с действием ServeFile. Перенаправление в существующий файл может быть проще. Я оставляю оригинальный метод, который я написал выше, и добавив альтернативную один здесь:

public ActionResult ServeFile(string filePath) 
    { 
     filePath = CleanFilePath(filePath); 
     var absolutePath = Server.MapPath(filePath); 

     if (System.IO.File.Exists(absolutePath)) 
     { 
      return RedirectPermanent(filePath); 
     } 

     return HttpNotFound(); 
    } 
+0

Спасибо Nathan - я думаю, что есть проблема с бит кода, где вы возвращаете HttpNotFound(); - подробности в моем отредактированном вопросе. - оценено – justSteve

0

Я считаю, что Андерсон @ Натан предоставил хороший ответ, но он кажется неполным.

Если вы хотите исправить опечатки и типы такие же простые, как вы упомянули, вы можете использовать код Натана, но прежде чем пытаться найти файл, вы удаляете любые символы плюса или восклицательного знака на пути, и вы можете сделать это нравится:

String sourcestring = "source string to match with pattern"; 
String matchpattern = @"[+!]"; 
String replacementpattern = @""; 
Console.WriteLine(Regex.Replace(sourcestring,matchpattern,replacementpattern)); 

Сформирован этот код из My Regex Tester инструмента.

Это код, который вам нужен. Этот код также удаляет любой символ + из имени файла. Если вы не хотите этого поведения, вы можете выбрать подстроку без имени файла и только заменить + и! символов перед именем файла.

+0

Это было полезно - thx. – justSteve

+0

@justSteve, то почему бы не перенести его и не отметить его как правильный ответ, чтобы другие могли быстрее добраться до него? –

+0

Полезная, но не настоящая точка вопроса, не так ли? Как насчет принятия последующих мер? – justSteve

Смежные вопросы