ASP.NET Charting Control больше не работает с .NET 4 - PullRequest
6 голосов
/ 13 апреля 2010

Я только что обновился до .NET 4, и мой элемент управления диаграммой ASP.NET больше не отображается.

В .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»), так что это, очевидно, где изменение пути происходит от.

Все, что я сделал, это переключил сборку System.Web.DataVisualization с 3.5 на 4.0.

Любая помощь с благодарностью.

Ответы [ 3 ]

18 голосов
/ 15 июля 2010

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

protected void Application_Start() {
    ...
    RouteTable.Routes.Ignore("{*pathInfo}", new { pathInfo = @"^.*(ChartImg.axd)$" });
    ...
}
8 голосов
/ 30 апреля 2010

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

Проблема заключалась в том, что свойство HttpContext.Current.Request.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.Current.Request.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, вместо обработчика Chart вызывался обработчик MVC.

Было найдено 3 способа справиться с этим (подробности см. Ниже):

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

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

  • Диспетчер IIS 6.0
  • Свойства -> Домашний каталог -> Конфигурация
  • Вкладка Mappings
  • Исполняемый файл: c: \ winnt \ microsoft.net \ framework \ v4.0.30319 \ aspnet_isapi.dll, расширение: .mvc

(2) Мы обнаружили, что добавление некоторых записей таблицы маршрутов будет работать, но нам пришлось учесть все возможные глубины в путях, чтобы ASP.NET MVC игнорировал ChartImg.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;
           }
       }
    }
2 голосов
/ 16 декабря 2010

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

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

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

Мне также пришлось изменить ImageLocation, чтобы он был не относительным (добавив /Temp/), поскольку это также вызывало проблему при переборе ChartControl DataPoints в некотором коде позади. *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...