JSON Compression attribute - asp.net

I have been using a compression attribute I found on the web, which is working very well for us.
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpRequestBase request = filterContext.HttpContext.Request;
string acceptEncoding = request.Headers["Accept-Encoding"];
if (string.IsNullOrEmpty(acceptEncoding)) return;
acceptEncoding = acceptEncoding.ToUpperInvariant();
HttpResponseBase response = filterContext.HttpContext.Response;
if (acceptEncoding.Contains("GZIP"))
{
response.AppendHeader("Content-encoding", "gzip");
response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
}
else if (acceptEncoding.Contains("DEFLATE"))
{
response.AppendHeader("Content-encoding", "deflate");
response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
}
}
the problem I have is that when an exception is thrown, then the screen displays the compressed content (I think!).. it looks like this..
xi��V�4��^ :b���$I"i#!c{��`$c��'wy�N�������H:��38�YS�b?ߕ�!`WSϙ��萧̬n��H����:V(ylZ� �ωԱ��Ϟӱ=�囥�ֺ���V��/>�^R���$٣����T�����J�oRݬz���?6$�<��KՔ��B0�x��V$�����F�h+Ǐ���!���0J��ɒ�h��+VR�p�ۊ�������!��-cccs�Z�%��2{�Ѿ��r�����۩/�,�n��n�f���tܳu�}����.+t��]���̆�����,�c��-�H0)J������dP�� �� ��/�|��#�Z�]O
My question is, is it possible to somehow work around this? Any way I can get this action to work nicely with exceptions?

You can remove the compression filter in Application_Error:
protected void Application_Error(object sender, EventArgs e)
{
(sender as HttpApplication).Response.Filter = null;
}
Alternatively, you can try updating the Content-Encoding response header appropriately but I haven't tried that so not sure if it's going to work.

Related

Exception handling in Application_Error, what is sender.Context.Request?

I have Exception-handling code in my Application_Error. I got the code from stackoverflow, its working.
protected void Application_Error(Object sender, EventArgs e)
{
string currentController = "";
string currentAction = "";
HttpContext httpContext = ((MvcApplication)sender).Context;
HttpRequestWrapper httpRequest = new HttpRequestWrapper(httpContext.Request);
RouteData currentRouteData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));
if (!(currentRouteData == null))
{
if (currentRouteData.Values["controller"] != null && !String.IsNullOrEmpty(currentRouteData.Values["controller"].ToString()))
{
currentController = currentRouteData.Values["controller"].ToString();
}
if (currentRouteData.Values["action"] != null && !String.IsNullOrEmpty(currentRouteData.Values["action"].ToString()))
{
currentAction = currentRouteData.Values["action"].ToString();
}
}
var exception = Server.GetLastError();
if (exception == null)
return;
// Clear the error
Server.ClearError();
Models.Exception ex = new Models.Exception();
ex.ErrorMessage = exception.Message;
ex.ErrorUrl = String.Format("{0}/{1}", currentController, currentAction);
FreelancerDB.SaveExceptions(ex);
Response.Redirect("~/WebsiteAccess/SystemError");
}
The problem is that I dont understand what is happening in these 2 linies:
HttpContext httpContext = ((MvcApplication)sender).Context;
HttpRequestWrapper httpRequest = new HttpRequestWrapper(httpContext.Request);
Can anyone explain what is happening here?
Nothing is happening there, the httpRequest variable isn't used afterwards.
It does give you a reference to the request during which the exception was generated, might you need it.

Passing parameters to remote SSRS report from ASP.NET MVC application

I have an ASP.NET MVC application that uses SSRS for reporting (using a web form and report viewer). I would like to pass two parameters dynamically to the remote report. My current implementation stores the parameters in session, which works fine on VS Development Server, but the variable is null on IIS, upon retrieval in the web form.
Here is the controller method that calls the view
public ActionResult ShowReport(string id)
{
var reportParameters = new Dictionary<string, string>();
reportParameters.Add("Param1", id);
reportParameters.Add("Param2", "user1");
Session["reportParameters"] = reportParameters;
return View("ReportName");
}
And here is how I attempt to retrieve the parameters from the web form
protected void Page_Load(object sender, EventArgs e)
{
var reportParameters = (Dictionary<string, string>)Session["reportParameters"];
foreach (var item in reportParameters)
{
ReportParameter rp = new ReportParameter(item.Key, item.Value);
ReportViewer1.ServerReport.SetParameters(rp);
}
}
Anyone know why Session["reportParameters"] is null?
Or is there some other way of passing these parameters?
You can do it too:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
try
{
var js = new JavaScriptSerializer();
string reportPath= Request.QueryString["LocalReport"];
string parametersTemp = Request.QueryString["ParametersReport"];
List<ReportParameter> parameters = null;
if (parametrosTemp != "")
{
parameters = JsonConvert.DeserializeObject
<List<ReportParameter>>(parametrosTemp);
}
GenerateReport(reportPath, parameters );
}
catch (Exception ex) {
statusReport.Value = ex.Message;
}
}
}
private void GenerateReport(string reportPath, List<ReportParameter> reportParameters)
{
reportCurrent.ProcessingMode = ProcessingMode.Remote;
ServerReport serverReport = reportCurrent.ServerReport;
serverReport.ReportServerUrl =
new Uri(AppSettings.URLReportServer);
serverReport.ReportPath = reportPath;
serverReport.Refresh();
if (reportParameters != null)
{
reportCurrent.ServerReport.SetParameters(reportParameters);
}
}
Is the problem that Session["reportParameters"] is null or is it that you don't get any parameters added to your report? Because your code, as it stands, won't add parameters to your report even if you pass them across properly and so the report parameters will be null.
SetParameters takes IEnumerable<ReportParameter> (usually a List), not a ReportParameterobject. Your code should look more like this:
protected void Page_Load(object sender, EventArgs e)
{
var reportParameters = (Dictionary<string, string>)Session["reportParameters"];
List<ReportParameter> parameters = new List<ReportParameter>();
foreach (var item in reportParameters)
{
parameters.Add(new ReportParameter(item.Key, item.Value););
}
ReportViewer1.ServerReport.SetParameters(parameters);
}

sqlexception 'timeout expired'?

I have some code in the global.asax file in my application. Each time I debug my website I get a sqlexception for some reason:
void Application_AuthorizeRequest(object sender, EventArgs e)
{
if (Membership.GetUser() != null && Roles.IsUserInRole("UnFilled")) // this is where I get the exception
{
if (Response.Cookies["Expiration"] == null)
{
HttpRequest request = Context.Request;
HttpResponse response = Context.Response;
response.ContentType = ".aspx";
response.Write(request.Url.Host + "/Activate.aspx?account="+Membership.GetUser().Email);
}
}
}
anyone know why I get this, how can I solve it?
I have found an answer, but not sure why it works. It seems to work if I place the coding into a custom http handler.
Thanks to all that contributed.

How to compress asp.net page in code level?

I added a method called Application_PreRequestHandlerExecute in global.ascx like this:
void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
string cTheFile = HttpContext.Current.Request.Path;
string sExtentionOfThisFile = System.IO.Path.GetExtension(cTheFile);
if (sExtentionOfThisFile.Equals(".aspx", StringComparison.InvariantCultureIgnoreCase))
{
HttpApplication httpApp = (HttpApplication)sender;
string acceptEncoding = httpApp.Request.Headers["Accept-Encoding"];
if (string.IsNullOrEmpty(acceptEncoding))
{
return;
}
acceptEncoding = acceptEncoding.ToLower();
System.IO.Stream requestStream = httpApp.Response.Filter;
if (acceptEncoding.Contains("gzip"))
{
httpApp.Response.Filter = new System.IO.Compression.GZipStream(requestStream,
System.IO.Compression.CompressionMode.Compress);
httpApp.Response.AppendHeader("Content-Encoding", "gzip");
}
else if (acceptEncoding.Contains("deflate"))
{
httpApp.Response.Filter = new System.IO.Compression.DeflateStream(requestStream,
System.IO.Compression.CompressionMode.Compress);
httpApp.Response.AppendHeader("Content-Encoding", "deflate");
}
}
}
It worked when browse normal page.
but if a page contains UPDATE-PANEL error will happen.
I get a PageRequestParserException.
when update-panel async post back, this error happens.
any idea?
I "fixed" by set the EnableEventValidation to false on my page and move compress logic to page's constructor.
Obviously this is not a good solution(close validation).
If anybody know a good solution, pls let me know.
and found that if the project's framework version is 3.5, all works fine,
but if the version is 2.0. this error will happen.

Exception breaks response compression

I wrote an IHttpModule that compresses my response using gzip (I return a lot of data.) in order to reduce response size. It is working great as long as the web service doesn't throw an exception. In case an exception is thrown, the exception is gzipped but the Content-encoding header disappears and the client doesn't know to read the exception.
Why is the header missing? I need to get the exception in the client.
Here is the module:
public class JsonCompressionModule : IHttpModule
{
public JsonCompressionModule()
{
}
public void Dispose()
{
}
public void Init(HttpApplication app)
{
app.BeginRequest += new EventHandler(Compress);
}
private void Compress(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
HttpRequest request = app.Request;
HttpResponse response = app.Response;
try
{
//Ajax Web Service request is always starts with application/json
if (request.ContentType.ToLower(CultureInfo.InvariantCulture).StartsWith("application/json"))
{
//User may be using an older version of IE which does not support compression, so skip those
if (!((request.Browser.IsBrowser("IE")) && (request.Browser.MajorVersion <= 6)))
{
string acceptEncoding = request.Headers["Accept-Encoding"];
if (!string.IsNullOrEmpty(acceptEncoding))
{
acceptEncoding = acceptEncoding.ToLower(CultureInfo.InvariantCulture);
if (acceptEncoding.Contains("gzip"))
{
response.AddHeader("Content-encoding", "gzip");
response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
}
else if (acceptEncoding.Contains("deflate"))
{
response.AddHeader("Content-encoding", "deflate");
response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
}
}
}
}
}
catch (Exception ex)
{
int i = 4;
}
}
}
Here is the web service:
[WebMethod]
public void DoSomething()
{
throw new Exception("This message get currupted on the client because the client doesn't know it gzipped.");
}
You should try to deal with the exception in page_error or in application_error event handlers.
I don't know what happens to the header but you probably can simulate and debug the Compress method by dividing by zero inside your application.
Check this link about global exception handling in ASP.NET

Resources