2010-04-13 13 views
6

Ho appena effettuato l'aggiornamento a .NET 4 e il controllo grafico ASP.NET non viene più visualizzato.ASP.NET Charting Control non funziona più con .NET 4

for .NET 3.5, il codice HTML prodotto dal controllo utilizzato per assomigliare a questo:

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

e ora, per NET 4, sembra che questo (notare il cambiamento nel percorso di origine):

<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;" /> 

Il grafico è in una vista parziale MVC che si trova in una cartella MVC zona chiamata "Statistiche" e un MVC Visualizzazioni cartella chiamata "Sommario" (vale a dire "/ aree/Statistiche/vista/Sintesi"), in modo da questo è ovviamente da dove viene il cambiamento di percorso.

Tutto ciò che ho fatto è passare l'assembly System.Web.DataVisualization da 3.5 a 4.0.

Qualsiasi aiuto molto apprezzato.

risposta

1

Grazie per le vostre risposte, ma non credo che il mio era un IIS6/Problema IIS7.

ho tracciato al fatto che il valore predefinito per ImageStorageMode su un ChartControl è cambiato UseImageLocation-UseHttpHandler. Il mio ChartControl ora ha alcuni attributi extra e tutto funziona bene.

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

ho dovuto cambiare anche l'ImageLocation di essere non-relativa (con l'aggiunta di /Temp/) come quella ha anche causato un problema quando l'iterazione di DataPoints il ChartControl s' in alcune code-behind.

7

Abbiamo avuto questo stesso problema su IIS 6 dopo l'aggiornamento da ASP.NET 3.5 a ASP.NET 4.0 con ASP.NET MVC. Tutto stava funzionando bene su IIS 7, ma IIS 6 ci ha dato un problema.

Il problema è che la proprietà HttpContext.Current.Request.CurrentExecutionFilePath dato un risultato diverso in IIS 6 e IIS 7:

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

che ha portato gli URL per i grafici come:

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

Il ChartHttpHandler ha una funzione in là che calcola il percorso base al largo la 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?"); 
} 

Il modo in cui l'URL UrlRewriting di ASP.NET funzionava, poiché i percorsi di ChartImg.axd avevano ancora .mvc in essi, il gestore MVC veniva richiamato invece del gestore del grafico.

c'erano 3 modi abbiamo trovato a che fare con esso (vedi sotto per i dettagli):

  1. Aggiungere un mapping di script esplicito per ".mvc" al ASP.NET 4.0 dll
  2. Aggiungete un po 'aggiuntiva ignorare le rotte per la tabella di route per coprire permutazioni
  3. sovrascrivere il execute() di controller e mettere in un reindirizzamento al /ChartImg.axd

(1) Si scopre che se abbiamo aggiunto una mappa di script per .mvc tramite IIS 6.0 per .mvc la richiesta.CurrentExecutionFilePath otterrebbe calcolato come il percorso della directory principale come volevamo che invece di come il percorso più profondo

  • Gestione IIS 6.0
  • Proprietà -> Home directory -> Configurazione
  • Mapping scheda
  • eseguibili: C: \ winnt \ microsoft.net \ framework \ v4.0.30319 \ aspnet_isapi.dll, Extension: .mvc

(2) Abbiamo scoperto che annuncio le voci della tabella di routing funzionerebbero, ma dovevamo tenere conto di tutte le profondità possibili nei percorsi per far sì che ASP.NET MVC ignorasse ChartImg.axd se fosse profondamente incorporato nel percorso e non nella radice:

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) eseguendo l'override del Execute() su tutti i nostri controllori facendo un controller di base che tutti i nostri controllori ereditano da, potremmo ignorare a livello globale l'Execute() per conto di questa situazione e reindirizzare a/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; 
      } 
     } 
    } 
+1

l'ulteriore RouteTable.Routes.IgnoreRoute ha fatto il trucco per noi. – badMonkey

18

Mentre la soluzione di @ Michael è informativa sul perché esiste un problema, c'è una soluzione più semplice. Quando si registrano i percorsi nei controller di gestire in global.asax.cs, si potrebbe aggiungere un percorso ignorato con un contstraint, come segue:

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

La risposta di Michael Ferrante è eccellente - ma non posso votare questa soluzione abbastanza ... rallegra Kevin –

Problemi correlati