开发者

Object reference not set to an instance of an object using Chart Control and MVC

I am trying to create a web site using ASP.NET (C#) and MVC. I have searched everywhere for an answer and am hoping for some help here.

Ideas and some code taken from: http://www.codecapers.com/post/Build-a-Dashboard-With-Microsoft-Chart-Controls.aspx

I was able to make the above work with a simple MVC project and bogus data.

I am trying to display a chart in a Partial View and keep getting the following error: Object reference not set to an instance of an object

I am not sure why I am getting this. When debugging, the list shows that it has the one chart in it. I am also able to print out information about the chart (i.e. height, width) that were set in the model. I just cannot render it in the partial view. Creating the chart as an image will not be useful to me.

Thanks in advance for your help!

I don't think it has anything to do with web.config but will include it anyways:

web.config

    <configuration>
      <appSettings>
        <add key="ChartImageHandler" value="Storage=file;Timeout=20;Url=/tempImages/;"/>
      </appSettings>
      <system.web>
      <httpHandlers>
         <add verb="GET,HEAD,POST" path="ChartImg.axd" type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/>
      <add verb="GET,HEAD,POST" path="Reserved.ReportViewerWebControl.axd" type="Microsoft.Reporting.WebForms.HttpHandler,     Microsoft.ReportViewer.WebForms, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"   />
    </httpHandlers>
    <compilation debug="true" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add assembly="System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      </assemblies>
    </compilation>
    <authentication mode="Forms">
      <forms loginUrl="~/Account/LogOn" timeout="2880"/>
    </authentication>
    <pages>
      <namespaces>
        <add namespace="System.Web.Mvc"/>
        <add namespace="System.Web.Mvc.Ajax"/>
        <add namespace="System.Web.Mvc.Html"/>
        <add namespace="System.Web.Routing"/>
      </namespaces>
      <controls>
        <add tagPrefix="asp" namespace="System.Web.UI.DataVisualization.Charting" assembly="System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      </controls>
    </pages>
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <modules runAllManagedModulesForAllRequests="true"/>
    <handlers>
      <remove name="ChartImageHandler"/>
      <add name="ChartImageHandler" preCondition="integratedMode" verb="GET,HEAD,POST" path="ChartImg.axd" type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    </handlers>
  </system.webServer>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

Controller

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Dashboard.WebUI.Models;

namespace Dashboard.WebUI.Controllers
{
    public class DashboardController : Controller
    {
        //
        // GET: /Dashboard/

        public ActionResult Index()
        {
            //LineSummaryModel model = new LineSummaryModel();
            PieChartModel model = new PieChartModel();
            return View(model);
        }

    }
}

Model

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI.DataVisualization;
using System.Web.UI.DataVisualization.Charting;

namespace Dashboard.WebUI.Models {
    public class PieChartModel {
        public PieChartModel() {
        }

        internal class PieChartData {
            public String Title { get; set; }
            public String[] Data { get; set; }
            public double[] xValues { get; set; }
            public double[] yValues { get; set; }
        }

        private Chart BuildServerPieChart() {
            String[] temp = { "France", "Canada", "Germany", "USA", "Italy" };
            double[] x = {1.0, 2.3, 4.5, 5.5, 5.6 };
            double[] y = {1.0, 2.0, 3.0, 4.0, 5.0 };

            PieChartData data = new PieChartData {
                Title = "Test Server",
                Data = temp,
                xValues = x,
                yValues = y
            };

            return BindChartData(data);
        }

        private Chart BindChartData(PieChartData data) {
            Chart chart = new Chart();
            chart.Width = 150;
            chart.Height = 300;
            chart.Attributes.Add("align", "left");

            chart.Titles.Add(data.Title);
            chart.ChartAreas.Add(new ChartArea());

            chart.Series.Add(new Series());

            chart.Legends.Add(new Legend("Countries"));
            chart.Legends[0].TableStyle = LegendTableStyle.Auto;

            chart.Legends[0].Docking = Docking.Bottom;

            chart.Series[0].ChartType = SeriesChartType.Pie;

            for(int i = 0; i < data.xValues.Length; i++){
                double x = data.xValues[i];
                double y = data.yValues[i];

                int ptIdx = chart.Series[0].Points.AddXY(x, y);
                var c = data.Data[i];

                DataPoint pt = chart.Series[0].Points[ptIdx];
                pt.ToolTip = c + ""+ x;
            }
            chart.Series[0].Legend = "Countries";
            return chart;
        }

        public List<Chart> PieCharts {
            get {
                List<Chart> charts = new List<Chart>();
                charts.Add(BuildServerPieChart());
                return charts;
            }
        }


    }
}

Master Page (Partial)

<!-- CONTENT -->
                    <div id="fps-main" style="width: 100%">
                        <div>
                            <asp:ContentPlaceHolder ID="LineSummary" runat="server">
                            </asp:ContentPlaceHolder>
                        </div>
                        <div>
                            <asp:ContentPlaceHolder ID="MiddleRow" runat="server">
                            </asp:ContentPlaceHolder>
                        </div>
                        <div>
                            <asp:ContentPlaceHolder ID="BottomRow" runat="server">
                            </asp:ContentPlaceHolder>
                        </div>
                    </div>
                    <!-- //CONTENT -->

Index.aspx

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Dashboard.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
<%@ Register Assembly="System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
Namespace="System.Web.UI.DataVisualization.Charting" TagPrefix="asp" %>
<asp:Content  ContentPlaceHolderID="TopSpotLight" runat="server">
    <% Html.RenderPartial("TopSpotlight"); %>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="LineSummary" runat="server">
     <% Html.开发者_Python百科RenderPartial("LineSummary"); %>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="BottomRow" runat="server">
    <h2>Section 3</h2>
</asp:Content>

Parital View (Line Summary.ascx)

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Dashboard.WebUI.Models.PieChartModel>" %>
<%@ Register Assembly="System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
Namespace="System.Web.UI.DataVisualization.Charting" TagPrefix="asp" %>

    <h2>Line Summary</h2>
    <%
        //Error Occurs here but I don't think this is the problem
        foreach (Chart chart in Model.PieCharts) {

            try {

                //In this section, I tried to render the control a couplie
                //different ways. Neither worked.
                PieSummaryChartPanel.Controls.Add(chart);
                //This prints out the correct height I set in model
                Response.Write(chart.Height + "<br />");
                HtmlTextWriter writer = new HtmlTextWriter(Page.Response.Output);
                chart.RenderControl(writer);

            } catch (System.NullReferenceException e) {
                Response.Write("ERROR:  " + e.Message);
            }

        }

            //Response.Write("Test " + LineSummaryChartPanel.BorderWidth.Value);
        //}
    %>

    <asp:Panel ID="PieSummaryChartPanel" runat="server"></asp:Panel>

I am not sure why, if it is null, I can print out the properties of the object. Thanks for your help.

Server Error in '/' Application.
    Object reference not set to an instance of an object.
    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

    Source Error:

    Line 11:         
    Line 12: 
    Line 13:         foreach (Chart chart in Model.PieCharts) {
    Line 14:             //if (chart != null && PieSummaryChartPanel != null) {
    Line 15:                // try {


    Source File: c:\Users\Scott\Documents\Projects\Visual Studio 2010\Projects\DashboardSolution\Dashboard.WebUI\Views\Shared\LineSummary.ascx    Line: 13

    Stack Trace:

    [NullReferenceException: Object reference not set to an instance of an object.]
       System.Web.UI.DataVisualization.Charting.ChartHttpHandler.GetHandlerUrl() +96
       System.Web.UI.DataVisualization.Charting.ChartHttpHandler.GetUrl(String query, String fileKey, String currentGuid) +32
       System.Web.UI.DataVisualization.Charting.ChartHttpHandler.GetChartImageUrl(MemoryStream stream, String imageExt) +339
       System.Web.UI.DataVisualization.Charting.Chart.Render(HtmlTextWriter writer) +420
       System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
       System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
       System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
       System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +208
       System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
       System.Web.UI.WebControls.WebControl.RenderContents(HtmlTextWriter writer) +10
       System.Web.UI.WebControls.WebControl.Render(HtmlTextWriter writer) +32
       System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
       System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
       System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
       ASP.views_shared_linesummary_ascx.__Render__control1(HtmlTextWriter __w, Control parameterContainer) in c:\Users\Scott\Documents\Projects\Visual Studio 2010\Projects\DashboardSolution\Dashboard.WebUI\Views\Shared\LineSummary.ascx:13
       System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +109
       System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
       System.Web.UI.Control.Render(HtmlTextWriter writer) +10
       System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
       System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
       System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
       System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +208
       System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
       System.Web.UI.Page.Render(HtmlTextWriter writer) +29
       System.Web.Mvc.ViewPage.Render(HtmlTextWriter writer) +56
       System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
       System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
       System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3060


I'm not quite sure if your problem is the same as mine, but I've come across this problem too. For me it turned out that at some point during rendering of the chart the ChartHttpHandler calls its (private) static GetHandlerUrl() method which contains the following line:

string str = Path.GetDirectoryName(HttpContext.Current.Request.CurrentExecutionFilePath ?? "").Replace(@"\", "/");

Unfortunately for me (and possibly you) the way my URL rewriting code works the value for 'HttpContext.Current.Request.CurrentExecutionFilePath' can sometimes be '/' and Path.GetDirectoryName() returns null for '/'.

Since they decided to smack a .Replace() straight to the result of the GetDirectoryName() result you end up with a nasty NullReferenceException.

For me the solution was to just make sure there's never a chart on the root page of the site... yeah, really... (Did win me an 'ugliest workaround of the year'-prize though)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜