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

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.

Related

ELMAH generates errors in quick succession

In our intranet there are some clinks with href pointing to my applcation. When any of the links is clicked and browser redirects, ELMAH generates the hundreds of repeating errors below for 10 seconds or so .
System.Web.HttpException: Server cannot set status after HTTP headers have been sent.
Generated: Tue, 13 Dec 2016 17:20:43 GMT
System.Web.HttpException (0x80004005): Server cannot set status after HTTP headers have been sent.
at System.Web.HttpResponse.set_StatusCode(Int32 value)
at System.Web.Mvc.HandleErrorAttribute.OnException(ExceptionContext filterContext)
at System.Web.Mvc.ControllerActionInvoker.InvokeExceptionFilters(ControllerContext controllerContext, IList`1 filters, Exception exception)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult)
My application has the following code in the Application_BeginRequest() and Application_Error() which set statuscode. I am not sure if it has anything to do with it.
protected void Application_BeginRequest(object sender, EventArgs e) {
Response.BufferOutput = true;
//enforce HTTPS
if (!HttpContext.Current.Request.IsLocal && !Request.IsSecureConnection )
{
bool addHttpsAttribute = true;
foreach (Filter filter in GlobalFilters.Filters)
{
if (filter.Instance is RequireHttpsAttribute)
{
addHttpsAttribute = false;
break;
}
}
if (addHttpsAttribute)
GlobalFilters.Filters.Add(new RequireHttpsAttribute());
}
}
protected void Application_Error(object sender, EventArgs e) {
Response.BufferOutput = true;
var httpContext = HttpContext.Current;
var currentRouteData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));
var currentController = " ";
var currentAction = " ";
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 ex = Server.GetLastError();
var controller = new myApp.Controllers.ErrorController();
var routeData = new RouteData();
var action = "OtherError";
if (ex is HttpException) {
var httpEx = ex as HttpException;
switch (httpEx.GetHttpCode()) {
case 404:
action = "NotFound";
break;
// others if any
default:
action = "OtherError";
break;
}
}
httpContext.ClearError();
httpContext.Response.Clear();
httpContext.Response.StatusCode = ex is HttpException ? ((HttpException) ex).GetHttpCode() : 500;
httpContext.Response.TrySkipIisCustomErrors = true;
routeData.Values["controller"] = "Error";
routeData.Values["action"] = action;
controller.ViewData.Model = new myApp.Models.HandleErrorInfo(ex, currentController, currentAction);
((IController) controller).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData));
Context.ApplicationInstance.CompleteRequest();
}

Trying to prevent session tampering works on local environment but not on prod server

So i want to prevent session tampering in my site and i implemented this in global.asax. What im doing is im generating a hash key using the GenerateHashKey function. which basically uses the browser version,userhost address etc to create a hash key. This hash key im attaching to ASP.NET_SessionId cookie. Now this works perfectly in local environment. but as soon as i host it to prod server, the "Invalid" exception is thrown the first time and then it works fine. why is this happening
I used this article
http://www.codeproject.com/Articles/859579/Hack-proof-your-asp-net-applications-from-Session
protected void Application_BeginRequest(object sender, EventArgs e)
{
try
{
if (Request.Cookies["ASP.NET_SessionId"] != null && Request.Cookies["ASP.NET_SessionId"].Value != null)
{
string newSessionID = Request.Cookies["ASP.NET_SessionId"].Value;
//Check the valid length of your Generated Session ID
if (newSessionID.Length <= 24)
{
//Log the attack details here
Response.Cookies["ASP.NET_SessionId"].Expires = DateTime.Now.AddDays(-30);
Response.Cookies["ASP.NET_SessionId"].Value = null;
throw new HttpException("Empty");
}
//Genrate Hash key for this User,Browser and machine and match with the Entered NewSessionID
if (GenerateHashKey() != newSessionID.Substring(24))
{
//Log the attack details here
Response.Cookies["TriedTohack"].Value = "True";
Response.Cookies["ASP.NET_SessionId"].Expires = DateTime.Now.AddDays(-30);
Response.Cookies["ASP.NET_SessionId"].Value = null;
throw new HttpException("Invalid:"+newSessionID);
}
//Use the default one so application will work as usual//ASP.NET_SessionId
Request.Cookies["ASP.NET_SessionId"].Value = Request.Cookies["ASP.NET_SessionId"].Value.Substring(0, 24);
}
}
catch(Exception Ex)
{
if (Ex.Message == "Invalid")
{
Response.Redirect(string.Format("~/PraiseError.aspx?Message={0}", Uri.EscapeDataString(Ex.Message)));
}
else
{
Response.Redirect("~/Home.aspx");
}
}
}
protected void Application_EndRequest(object sender, EventArgs e)
{
string gn = GenerateHashKey();
try
{
//Pass the custom Session ID to the browser.
if (Response.Cookies["ASP.NET_SessionId"] != null)
{
Response.Cookies["ASP.NET_SessionId"].Value = Request.Cookies["ASP.NET_SessionId"].Value.Replace(gn, "") + gn;
}
else
{
Response.Cookies["ASP.NET_SessionId"].Value = Request.Cookies["ASP.NET_SessionId"].Value + gn;
}
}
catch
{
Response.Cookies["ASP.NET_SessionId"].Value = Request.Cookies["ASP.NET_SessionId"].Value + gn;
}
}
private string GenerateHashKey()
{
StringBuilder myStr = new StringBuilder();
myStr.Append(Request.Browser.Browser);
myStr.Append(Request.Browser.Platform);
myStr.Append(Request.Browser.MajorVersion);
myStr.Append(Request.Browser.MinorVersion);
myStr.Append(Request.UserHostAddress);
//myStr.Append(Request.LogonUserIdentity.User.Value);
SHA1 sha = new SHA1CryptoServiceProvider();
byte[] hashdata = sha.ComputeHash(Encoding.UTF8.GetBytes(myStr.ToString()));
return Convert.ToBase64String(hashdata);
}

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.

Resources