Why can I write a session when SessionStateBehavior.ReadOnly is installed on the controller and I don't care?

I have several controllers with SessionStateBehavior.ReadOnly to enable parallel processing of multiple ajax requests.

But I noticed that this does not stop me from writing to the session (unlike SessionStateBehavior.Disabled, which throws an exception).

My application uses Microsoft Charting, and the chart and image map is generated in response to an ajax request, where the chart is stored in the session until the image browser is displayed by the browser, after which the src image launches the browser for the request that is retrieved from the session. Thus, there is no problem trying to read from a session before writing it.

Everything works fine, I have several ajax handlers being processed in parallel, and my diagrams are returning correctly, so it matters that I declared SessionStateBehavior.ReadOnly when I write to the session?

using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Web.Mvc; using System.Web.UI.DataVisualization.Charting; using Mdl.Rcm.Web.Areas.Dashboards.Models; using Mdl.Web.Security; using Mdl.Persistence.UoW; using Mdl.Rcm.Business.Dashboards; using Mdl.Rcm.Business.Dashboards.Models; using Mdl.Rcm.Web.Areas.Dashboards.Charts; using Mdl.Rcm.Web.Areas.Dashboards.Charts.OrganisationConnectionsByRole; using Mdl.Web.Mvc; namespace Mdl.Rcm.Web.Areas.Dashboards.Controllers { /// <summary> /// Controller for the Organisation Connections By Role chart. /// </summary> [SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)] [RedirectingAuthorize(Roles = "Dashboards")] [Area(IsSiteRoot = false)] public class ChartOrganisationConnectionsByRoleController : Controller { private readonly IRelationshipAndRiskService relationshipAndRiskService; private readonly IConfigurationService configurationService; private readonly IOrganisationConnectionsByRoleChartBuilder chartBuilder; private readonly IListService listService; private BarConfiguration barConfiguration; private const string TempDataKey = "OrganisationConnectionsByRoleData"; public ChartOrganisationConnectionsByRoleController(IOrganisationConnectionsByRoleChart organisationConnectionsByRoleChart, IRelationshipAndRiskService relationshipAndRiskService, IConfigurationService configurationService, IOrganisationConnectionsByRoleChartBuilder chartBuilder, IListService listService) { this.relationshipAndRiskService = relationshipAndRiskService; this.configurationService = configurationService; this.chartBuilder = chartBuilder; this.listService = listService; } /// <summary> /// Standard Organisation Connections by Role component loader /// </summary> /// <param name="listId">The list id.</param> /// <param name="degree">The active degree.</param> /// <param name="barIndex">Index of the active bar.</param> /// <returns></returns> [HandleAjaxError] public ActionResult Load(int listId, int degree, int barIndex) { using (UnitOfWork.Start("Analysis")) { // Get the data var relationshipPlanningData = GetChartDataForInitialLoadParentComponent(listId); var connectionsFound = relationshipPlanningData.SeriesModels.Count > 0; var listName = listService.GetListName(listId).Name; var information = new InformationModel(degree, true) { ConnectionsFound = connectionsFound, NumberOfOrganisationsInList = relationshipPlanningData.TotalNumberOfOrganisations, ListName = listName }; return PartialView("OrganisationConnectionsByRoleComponent", new OrganisationConnectionsByRoleComponentModel { ListId = listId, ActiveDegree = degree, ActiveBarIndex = barIndex, BarConfiguration = configurationService.GetBarConfiguration(), ConnectionsFound = connectionsFound, Information = information}); } } /// <summary> /// Creates the Connections by Role chart and stores it in Session then returns the chart map. /// The chart image map is always created first, the chart is created as part of the process of creating the map. /// </summary> /// <returns></returns> public ActionResult Chart(Guid chartId, int listId) { using (UnitOfWork.Start("Analysis")) { barConfiguration = configurationService.GetBarConfiguration(); var relationshipPlanningData = GetChartDataForInitialLoadChart(); if (relationshipPlanningData.SeriesModels.Count == 0) { return PartialView("InfoMessage", "No connections found"); } // Set up the chart return GenerateChart(relationshipPlanningData, listId, chartId); } } private ActionResult GenerateChart(OrganisationConnectionsByRoleData relationshipPlanningData, int listId, Guid chartId) { var chartAndXPoints = chartBuilder.BuildChart(2, relationshipPlanningData, barConfiguration, SetActiveBarIndex(-1), listId); // Store the chart in session for retrieval by the browser as the src on an image tag. ChartSession.GenerateChartToSession(chartId, chartAndXPoints.Chart, Session); // Get y data for use client side var yPointsDataView = GetYPointsDataView(relationshipPlanningData); // Get x co-ordinates for use client side. Must be done after the chart has been generated to session. var xPointsView = GetXPointsView(chartAndXPoints.XPoints); // Render the image tag and image map return this.Chart(chartAndXPoints.Chart, xPointsView + yPointsDataView, chartId, "ConnectionsByRoleImage"); } /// <summary> /// Gets the chart data for use by the main component. /// </summary> /// <param name="listId">The list id.</param> /// <returns></returns> private OrganisationConnectionsByRoleData GetChartDataForInitialLoadParentComponent(int listId) { // This is the call from the load action so get the data and store it for use by the chart action to save the performance hit var data = relationshipAndRiskService.GetOrganisationConnectionsByRoleChartData(listId); TempData[TempDataKey] = data; return data; } /// <summary> /// Gets the chart data for use by the main component chart. /// </summary> /// <returns></returns> private OrganisationConnectionsByRoleData GetChartDataForInitialLoadChart() { // This call is from the chart action so use the data that was retreived on the load action return (OrganisationConnectionsByRoleData)TempData[TempDataKey]; } /// <summary> /// Return the Connections By Role chart from session. /// </summary> /// <returns></returns> public ActionResult ConnectionsByRoleImage(Guid chartId) { var chart = ChartSession.GetChartFromSession(chartId, Session); return File(chart, "image"); } /// <summary> /// Return the Connections By Role chart from session. /// </summary> /// <param name="listId">The list id.</param> /// <param name="degree">The active degree.</param> /// <param name="barIndex">Index of the active bar.</param> /// <returns></returns> public ActionResult ConnectionsByRoleActive(int listId, int degree, int barIndex) { using (UnitOfWork.Start("Analysis")) { barConfiguration = configurationService.GetBarConfiguration(); // Get the data var relationshipPlanningData = relationshipAndRiskService.GetOrganisationConnectionsByRoleChartData(listId); if (relationshipPlanningData.SeriesModels.Count == 0) { return PartialView("InfoMessage", "No connections found"); } // Set up the chart var chartAndXPoints = chartBuilder.BuildChart(SetActiveDegree(degree), relationshipPlanningData, barConfiguration, SetActiveBarIndex(-1), listId); var ms = new MemoryStream(); chartAndXPoints.Chart.SaveImage(ms, ChartImageFormat.Png); return File(ms.ToArray(), "image"); } } /// <summary> /// Gets the graph X points and render them as a javascript object for use by the view. /// </summary> /// <param name="xPoints">The x points.</param> /// <returns></returns> private string GetXPointsView(List<float> xPoints) { var model = new XPointsModel { ChartName = "Connections By Role", Points = xPoints }; return this.ViewAsString("XPoints", model); } /// <summary> /// Gets the Y points data and render them as a javascript object for use by the view. /// </summary> /// <param name="relationshipPlanningData">The relationship planning data.</param> /// <returns></returns> private string GetYPointsDataView(OrganisationConnectionsByRoleData relationshipPlanningData) { var degree1DataPoints = relationshipPlanningData.SeriesModels[0].DataPoints.Select(p => pY).ToList(); var degree2DataPoints = relationshipPlanningData.SeriesModels[1].DataPoints.Select(p => pY).ToList(); var model = new YPointsDegree1And2Model { ChartName = "Connections By Role", Degree1Data = degree1DataPoints, Degree2Data = degree2DataPoints }; return this.ViewAsString("YPointsDegree1And2", model); } private int SetActiveBarIndex(int barIndex) { if (barIndex == -1) { barIndex = barConfiguration.Bars.First(b => b.IsDefaultActive).Index; } return barIndex; } private static int SetActiveDegree(int degree) { if (degree == -1) { degree = 2; } return degree; } } } public class ChartSession { public static byte[] GetChartFromSession(Guid chartId, HttpSessionStateBase session) { // Get the chart from session var data = session[chartId.ToString()] as byte[]; // Clear the session session[chartId.ToString()] = null; return data; } public static void GenerateChartToSession(Guid chartId, Chart chart, HttpSessionStateBase session) { var ms = new MemoryStream(); chart.SaveImage(ms, ChartImageFormat.Png); session[chartId.ToString()] = ms.ToArray(); } 
+6
source share
1 answer

SessionStateBehavior indicates only ASP.NET what blocks to put on Session

See this question: SessionStateBehavior controller is ReadOnly and I can update the session variable

+5
source

All Articles