Passing long querystrings over urls shows page not found error(404) - c#

I have a "error.aspx" page which is there to mail me if any exception is caught. When I open the page manually, mysite.com/error.aspx, the page opens fine but when it is redirected by a catch block with the exception.message and exception.stackTrace as querystrings, I get an error "page not found". Are the querystrings directing the browser to open a different url? It works fine when run on localhost, though.
public void send_error(Exception ex)
{
Response.Redirect("error.aspx?time=" + DateTime.Now.ToString() + "&ex=" + ex.Message + "&st=" + ex.StackTrace.Replace("\n", " "), false);
}

If you check this Article, you will see that the max query length of url string is 2048 symbols for Internet explorer. Probably the url is bigger and because of that you have this problem. One solution is to save the desire message in the session as string and after that retrieve it on other pages.
string errorMessage = DateTime.Now.ToString() + " " + ex.Message + " " + ex.StackTrace.Replace("\n", " ");
Session["__ErrMessage"] = errorMessage;
When you are in other pages you can access this string like this:
string errMessage = "";
if(Session["__ErrMessage"] != null)
errMessage = Session["ErrMessage"].ToString();

Related

Response.Redirect not sending string

i've got a bit of a problem trying to set up a general error page in MVC.
I am handling all app errors in Global.asax.cs with the following code ->
protected void Application_Error(object sender, EventArgs e)
{
//if (Request.Url.ToString().StartsWith("http://localhost:"))
// return;
string msg;
Exception ex = Server.GetLastError().GetBaseException();
StringBuilder sb = new StringBuilder();
sb.AppendLine("Exception Found");
sb.AppendLine("Timestamp: " + System.DateTime.Now.ToString());
sb.AppendLine("Error in: " + Request.Url.ToString());
sb.AppendLine("Browser Version: " + Request.UserAgent.ToString());
sb.AppendLine("User IP: " + Request.UserHostAddress.ToString());
sb.AppendLine("Error Message: " + ex.Message);
sb.AppendLine("Stack Trace: " + ex.StackTrace);
msg = sb.ToString();
Server.ClearError();
Response.Redirect(string.Format("~/Error/Error?w={0}", msg ));
}
My problem is that i'm not getting a redirect. I see the same page URL and a blank page when i'm creating an error.
If i remove "errorMsg" and add a SIMPLE STRING, it works, redirects with the required param. Ex:
string test = "testme";
Response.Redirect(string.Format("~/Error/Error?w={0}", test));
That does redirect me to the error page with param "testme". What am i doing wrong here?
You to need escape all the parameters (UrlEncode). At the moment it is unescaped and has a whole bunch of new lines too.
Before you do that, I suggest you just append "hello world" parameter and re-display that to ensure your redirect page is working

Opening a PDF with search parameters just opens the PDF

I was requested to add some searching functionality to an existing system for the collection of PDFs that we have. I know about searching PDFs and opening them with search parameters and in a test application I wrote, it works like a dream. When trying to convert it over to our existing application the PDF opens but without the search terms or the advanced find of Acrobat Reader popping up. Any help would be greatly appreciated!
Here is a snippet of the cs code :
case "PDF":
string searchTerms = SearchWordsTB.Text;
searchTerms = searchTerms.Replace(',', ' ');
launchStr = "OpenPDF('" + e.Row.Cells[9].Text.Replace("\\", "/") + "','" + HttpUtility.UrlEncode(e.Row.Cells[2].Text) + "','" + e.Row.Cells[0].Text + "','" + searchTerms + "')";
break;
We are creating the list of documents on the fly and PDF is one of the options. Assuming I am understanding this correctly, A DataGrid is created with all these clickable rows that will execute a Javascript function when clicked. The Javascript function OpenPDF is shown below:
function OpenPDF(url, filename, ID, searchTerms) {
if (searchTerms.length > 0) {
window.open('FileViewer.aspx?name=' + filename + '&ID=' + ID + '&url=' + url + '#search="' + searchTerms + '"', 'mywindow' + windowCnt, 'width=800,height=600,location=no,resizable=yes');
}
else {
window.open('FileViewer.aspx?name=' + filename + '&ID=' + ID + '&url=' + url, 'mywindow' + windowCnt, 'width=800,height=600,location=no,resizable=yes');
}
windowCnt++;
}
From following the debugging in the CS code, I know that I am properly stripping out the commas in the search terms so that shouldn't be the problem. What currently happens is the PDF file will open up just fine, but the search terms are not being used. I have tried following the debugger through the Javascript (which for me has always been spotty at best) but the breakpoint is never hit. It should also probably be noted that the Javascript function is kept in a separate Javascript File and is not inline in the aspx page. And yes, we are correctly referencing the Javascript file. I will be more than happy to update this post with any extra info that is requested. Thanks in advance for any help!
I was able to achieve the desired results by using the http encode on the launch string as shown below.
launchStr = "OpenFile('" + HttpUtility.UrlEncode(e.Row.Cells[9].Text.Replace("\\", "/") + "#search=\"" + searchTerms + "\"") + "','" + HttpUtility.UrlEncode(e.Row.Cells[2].Text) + "','" + e.Row.Cells[0].Text + "','" + e.Row.Cells[1].Text + "')";
I then used the function to just open the window with the PDF in it. The problem I had was that without the HTTP Encode, the URL was just cutting off the search parameters. I believe this is because the #search="blah" isn't normally recognized as part of a URL and was therefore truncated. If anyone has a better reason, I would love to hear it.

How to get the current project name in C# code?

I want to send an email to myself when an exception is thrown. Using StackFrame object, I am able to get File Name, Class Name and even class method that throw the Exception, but I also need to know the project name as many of my ASP.NET project has the same file name, class name and method.
This is my code:
public static string JndGetEmailTextForDebuggingExceptionError(this Exception Ex)
{
StackFrame sf = Ex.JndGetStackFrame();
string OutputHTML = "<i><b><u>For Developer Use Only: </u></b></i>" + "<br>" +
"<br>" +
"Project Name: " + HttpContext.Current.ApplicationInstance.GetType().Assembly.GetName().Name + "<br>" + //Under discussion
"File Name: " + sf.GetFileName() + "<br>" +
"Class Name: " + sf.GetMethod().DeclaringType + "<br>" +
"Method Name: " + sf.GetMethod() + "<br>" +
"Line Number: " + sf.GetFileLineNumber() + "<br>" +
"Line Column: " + sf.GetFileColumnNumber() + "<br>" +
"Error Message: " + Ex.Message + "<br>" +
"Inner Message : " + Ex.InnerException.Message + "<br>";
return OutputHTML;
}
Thanks ALL.
You can use Assembly.GetCallingAssembly if you have your logging code in a separate library assembly, and call directly from your ASP.NET assembly to your library, and you mark the method so that it won't be inlined:
[MethodImpl(MethodImplOptions.NoInlining)]
public static string JndGetEmailTextForDebuggingExceptionError(this Exception Ex)
{
StackFrame sf = Ex.JndGetStackFrame();
string OutputHTML = "<i><b><u>For Developer Use Only: </u></b></i>" + "<br>" +
"<br>" +
"Project Name: " + Assembly.GetCallingAssembly().GetName().Name + "<br>" +
"File Name: " + sf.GetFileName() + "<br>" +
"Class Name: " + sf.GetMethod().DeclaringType + "<br>" +
"Method Name: " + sf.GetMethod() + "<br>" +
"Line Number: " + sf.GetFileLineNumber() + "<br>" +
"Line Column: " + sf.GetFileColumnNumber() + "<br>" +
"Error Message: " + Ex.Message + "<br>" +
"Inner Message : " + Ex.InnerException.Message + "<br>";
return OutputHTML;
}
On any entry points in your library that can end up wanting to log the project name, you'd have to record the calling assembly and mark it NoInlining, then pass that around internally.
If you're using .NET 4.5, there's an alternative way to do this: CallerFilePath. It has the same restrictions on entry points, and it returns the source path on your machine instead of the assembly name (which is probably less useful), but it's easier to know that it'll work (because it compiles it, just like optional parameters are compiled in), and it allows inlining:
public static string JndGetEmailTextForDebuggingExceptionError
(this Exception Ex, [CallerFilePath] string filePath = "")
{
StackFrame sf = Ex.JndGetStackFrame();
string OutputHTML = "<i><b><u>For Developer Use Only: </u></b></i>" + "<br><br>" +
"Source File Path: " + filePath + "<br>" +
...
For anyone looking for an ASP.NET Core compatible solution, the following should work;
System.Reflection.Assembly.GetEntryAssembly().GetName().Name
.NET Core API Reference
This ought to be enough
string projectName = Assembly.GetCallingAssembly().GetName().Name;
Edit* If you are running this from another assembly then you should use GetCallingAssembly instead.
You can use
HttpContext.Current.ApplicationInstance.GetType().Assembly.GetName().Name
If this returns App_global.asax...., change it to
HttpContext.Current.ApplicationInstance.GetType().BaseType.Assembly.GetName().Name
If you aren't running in an HTTP request, you will need some way to get ahold of the HttpContext.
This will return different results if you're in a Web Site project (as opposed to Web Application).
You can also use HttpRuntime.AppDomainAppPath to get the physical path on disk to the deployed site; this will work everywhere.
Reflection is the best way to find out product name,company name version like information.
public static string ProductName
{
get
{
AssemblyProductAttribute myProduct =(AssemblyProductAttribute)AssemblyProductAttribute.GetCustomAttribute(Assembly.GetExecutingAssembly(),
typeof(AssemblyProductAttribute));
return myProduct.Product;
}
}
And Another way like get direct project name
string projectName=System.IO.Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().Location).ToString();
Just adding my answer here.
For those who work with multiple Dlls in their projects, the correct answer is:
string projectName = Assembly.GetExecutingAssembly().FullName.Split(',')[0];

Input string format is not correct in ftp web request

I am creating a file on ftp server. But Before creating file on server I also check that it does not existing already. However, It is working fine most of the system but one of my client has problem. When he run the application, it throws the system.formatexception i-e input string is not in correct format.
I am unable to understand this problem. Can anybody help me?
The following is the code to create file.
public string createFile(string filename1)
{
StreamWriter sw1 = null;
System.Net.FtpWebRequest tmpReq1;
try
{
tmpReq1 = (System.Net.FtpWebRequest)System.Net.FtpWebRequest.Create("ftp://ftp.dunyameri.com/pt/" + filename1);
tmpReq1.Credentials = new System.Net.NetworkCredential("naveed#dunyameri.com", "xxxxx");
FtpWebResponse response = (FtpWebResponse)tmpReq1.GetResponse();
}
catch (WebException ex)
{
FtpWebResponse response2 = (FtpWebResponse)ex.Response;
if (response2.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
{
// I am creating file here
}
else
{
return ex.ToString();
}
}
return "File Created";
}
I haves searched on internet that it might be because of string contain 0 or dots. In this particular system case the file name contain dots and 0. Is it because of this type of file name?
Thanks,
Naveed
It seems that the error does not occur within "createFile(string filename1)". If so, the stack should be similar to this:
...
System.Convert.ToInt32(String value)
e2erta.e2erta1.YourFtpClass.createFile(string filename1) <- I would expect this line!
e2erta.e2erta1..ctor()
My best guess would be that filename1 starts with a / character. You can use the Path.Combine method to handle this case:
var path = Path.Combine("ftp://ftp.dunyameri.com/pt/", filename1);
var tmpReq1 = (System.Net.FtpWebRequest)System.Net.FtpWebRequest.Create(path);
...
Url should be something like "ftp://" + userName + ":" + password + "#" + serverAddress + ":" + serverPort + "/" + file.
Try to add port.
The class FtpWebRequest does not have a Create method seelink http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest_methods
The example shown on link casts WebRequest.Create to FtpWebRequest this might be the issue

submit sitemap to the google

System.Net.WebRequest reqGoogle = System.Net.WebRequest.Create("http://www.google.com/webmasters/tools/ping?sitemap=" + HttpUtility.UrlEncode("http://www.shree/SiteMap/'" + PortalName + "'/sitemap.xml"));
reqGoogle.GetResponse();
Code work fine when google is not blocked.For some region my administrator block the goole.After blocking google code gives an error. How to check the site first if it is blocked or not.plz help.
like this(?):
try
{
System.Net.WebRequest reqGoogle = System.Net.WebRequest.Create("http://www.google.com/webmasters/tools/ping?sitemap=" + HttpUtility.UrlEncode("http://www.shree/SiteMap/'" + PortalName + "'/sitemap.xml"));
reqGoogle.GetResponse();
}
catch(WebException ex)
{
MessageBox.Show("Google is blocked");
}

Categories