ASP.NET управление диаграммами больше не работает with.NET 4

Я только что обновился до .NET 4 и мой ASP.NET Chart Control больше не отображается.

для .NET 3.5 HTML, созданный элементом управления, выглядит следующим образом:

<img id="20_Chart" src="/ChartImg.axd?i=chart_5f6a8fd179a246a5a0f4f44fcd7d5e03_0.png&amp;g=16eb7881335e47dcba16fdfd8339ba1a" alt="" style="height:300px;width:300px;border-width:0px;" />

и теперь, для .NET 4, это выглядит так (Обратите внимание на изменение исходного пути):

<img id="20_Chart" src="/Statistics/Summary/ChartImg.axd?i=chart_5f6a8fd179a246a5a0f4f44fcd7d5e03_0.png&amp;g=16eb7881335e47dcba16fdfd8339ba1a" alt="" style="height:300px;width:300px;border-width:0px;" />

диаграмма находится в частичном представлении MVC, которое находится в папке области MVC под названием "статистика" и папке представлений MVC под названием " сводка "(т. е." /Areas/Statistics/Views/Summary"), так что это очевидно, откуда происходит изменение пути.

все, что я сделал, это переключить систему.Сеть.Сборка DataVisualization от 3.5 до 4.0.

любая помощь очень ценится.

3 ответов


хотя решение @Michael информативно о том, почему эта проблема существует, есть более простое решение. При регистрации маршрутов в контроллерах обрабатывайте в global.асакс.cs, вы можете добавить игнорируемый маршрут с contstraint, следующим образом:

protected void Application_Start() {
    ...
    RouteTable.Routes.Ignore("{*pathInfo}", new { pathInfo = @"^.*(ChartImg.axd)$" });
    ...
}

у нас была такая же проблема на IIS 6 после обновления с ASP.NET 3.5 - ASP.NET 4.0 с ASP.NET MVC. Все работало нормально на IIS 7, но IIS 6 дал нам проблему.

проблема заключалась в том, что HttpContext.Текущий.Запрос.Свойство CurrentExecutionFilePath дало другой результат в IIS 6 и IIS 7:

  • Url:/Controller.mvc/Action/1/2
  • IIS 6:/Controller.mvc/Action/1/2
  • IIS 7:/Controller.mvc

что привело к URL-адресам для диаграммы, как:

  • IIS 6:/Controller.mvc/Action/1/ChartImg.axd?i=chart_...
  • IIS 7:/ChartImg.axd?i=chart_...

у ChartHttpHandler есть функция, которая вычисляет путь на основе HttpContext.Текущий.Запрос.CurrentExecutionFilePath:

private static string GetHandlerUrl()
{
    string str = Path.GetDirectoryName(HttpContext.Current.Request.CurrentExecutionFilePath ?? "").Replace(@"\", "/");
    if (!str.EndsWith("/", StringComparison.Ordinal))
    {
        str = str + "/";
    }
    return (str + "ChartImg.axd?");
}

то, как ASP.NET UrlRewriting работал, так как пути к ChartImg.AXD по-прежнему не было .mvc в них вместо обработчика диаграммы вызывался обработчик MVC.

было 3 способа мы нашли, чтобы иметь дело с ним (см. ниже для деталей):

  1. добавить явную карту скриптов для ".mvc " к ASP.NET 4.0 dll
  2. добавьте некоторые дополнительные маршруты игнорирования в таблицу маршрутов, чтобы покрыть перестановки
  3. переопределите Execute () контроллера и поместите перенаправление обратно в /ChartImg.классов AXD

(1) Оказывается, что если мы добавили карту скрипта для .mvc через IIS 6.0 для .в MVC запрос.CurrentExecutionFilePath бы вам вычисляется как корневой путь, как мы хотели, а не как более глубокий путь

  • диспетчер IIS 6.0
  • Свойства -> Домашний Каталог -> Настройка
  • вкладка отображений
  • исполняемый файл: c:\winnt\microsoft.net\framework\v4.0.30319\aspnet_isapi.dll, Extension: .в MVC

(2) мы обнаружили, что добавление некоторых записей таблицы маршрутов будет работать, но мы должны были учитывать все возможные глубины в путях, чтобы получить ASP.NET MVC игнорировать Чартимг.axd, если бы он был глубоко встроен в путь, а не в корень:

RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
RouteTable.Routes.IgnoreRoute("{a}/{resource}.axd/{*pathInfo}");
RouteTable.Routes.IgnoreRoute("{a}/{b}/{resource}.axd/{*pathInfo}");
RouteTable.Routes.IgnoreRoute("{a}/{b}/{c}/{resource}.axd/{*pathInfo}");
RouteTable.Routes.IgnoreRoute("{a}/{b}/{c}/{d}/{resource}.axd/{*pathInfo}");

(3) путем переопределения Execute() на всех наших контроллерах, сделав базовый контроллер, который наследуют все наши контроллеры, мы могли бы глобально переопределить Execute() для учета этой ситуации и перенаправления в /ChartImg.классов AXD

   public partial class MyController: Controller
   {
      protected override void Execute(RequestContext cc)
       {
           // the url for chartimg.axd to be in the application root.  /Controller.mvc/Action/Param1/ChartImg.axd gets here first,
           // but we want it to go to /ChartImg.axd, in which case the IgnoreRoute does work and the chart http handler does it's thing.
           if (cc.HttpContext.Request.Url.AbsoluteUri.Contains("ChartImg.axd"))
           {
               var url = new UriBuilder(cc.HttpContext.Request.Url);
               url.Path = "/ChartImg.axd";
               cc.HttpContext.Response.Redirect(url.ToString());
               return;
           }
       }
    }

Спасибо за ваши ответы, но я не думаю, что у меня была проблема IIS6/IIS7.

Я проследил его до того, что значением по умолчанию для ImageStorageMode на ChartControl изменилась с UseImageLocation to UseHttpHandler. Мой ChartControl теперь имеет некоторые дополнительные атрибуты и все работает нормально.

<asp:Chart ... ImageStorageMode="UseImageLocation" ImageLocation="/Temp/ChartPic_#SEQ(300,3)">

мне также пришлось изменить ImageLocation быть не относительным (путем добавления /Temp/), поскольку это также вызвало проблему при итерации по ChartControl ' s DataPoints в некоторых кодом.