I have developed a web app a year ago aimed to work with IIS6.
Now we are moving to IIS7 and I thought, I'd do some integration tests.
One of this fails:
The web app is more or less a search-engine, giving a 404 or 500 (thanks to your google-advisor ...) when there weren't any results or the data-container is not loaded yet. With IIS6 this worked great: The page output was eg. result.aspx, showing some message and giving back the specified http status (set at codebehind).
Now with IIS7 this behaviour is broken: If I set the http status code at codebehind, my page won't be delivered anymore - instead showing the generic error page of IIS7.
No, I do not want to do any dirty hack with the customErrors-Section ...
I just want the original behaviour back!
Is there any way to do this?
Edit:
Consider following page
<%# Page Language="C#" AutoEventWireup="true"%>
<script runat="server">
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.Response.StatusCode = 404;
}
</script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
This page should be displayed
</div>
</form>
</body>
</html>
Vista + IIS7 = OK
2008 Server + IIS7 = Generic Error Page
have you tried this:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.Response.StatusCode = 404;
Response.TrySkipIisCustomErrors = true;
}
HttpResponse.TrySkipIisCustomErrors Property (System.Web)
Your problem is probably that you have tried to set the Status Code (which counts as part of the Header) at some point after you've starting sending the Body of the response i.e. your pages contents - in your case the message.
To solve this you can try setting Response.Buffer to true and then if you have to set a 404/500 response code then call Response.Clear() before setting the response code.
Note that if you are sending a 404/500 then there should generally be no body to the response (although the HTTP spec does allow for it)
Related
I am trying to use $.ajax.post using:
$.ajax({
type: "POST",
url: "http://localhost/products/SaveXML.aspx",
data: { name: "John", location: "Boston" }
}).done(function (msg) {
alert("Data Saved: " + msg);
});
});
SaveXML lookes like:
<%# Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script language="c#" runat="server">
public void testMethod()
{
string sayHello = "hello world";
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server"></form>
</body>
</html>
Eventually, I want to pass in some XML and have SaveXML handle it.
Does the code need to be in a code-behind? Does it need to be marked as a web method?
Can someone show me what this should look like please?
Thanks
You can use ASP.NET Page Methods with jQuery.
Check this:
Using jQuery to directly call ASP.NET AJAX page methods
The code needs indeed to be server side code (which doesn't mean you have to have a code behind file - what you have with your testMethod will work just fine, as it is in a server side context).
Since you are posting the data to the .aspx page, there is no need to use a web method. You can use Page_Load or OnInit to get the posted data (via the Request page property) and handle the posted data in it.
I am trying to display an image from my database. I have an generic handler to display the image. But my problem is that it doesn't get called. My code for calling the handler is
Image1.ImageUrl = "~/ShowImage.ashx?id=" + id;
where id is a number and ShowImage.ashx is the handler. The breakpoints in .ashx file doesn't get hit either. I am new to asp.net. So any help would be highly appreciated.
In this cases the steps that you need to follow is to see how the html is rendered.
So, right click on the html page, and "view page source".
There locate the point that the ShowImage.ashx is called, and see if the full rendered path is correct.
From there you simple correct the path.
Additional you can use the browser tools to see what browser looks for, and if he finds it or not. On google chrome for example you make right click, then inspect elements and then click on the network. There you can see with red, what files your page can not find, and you need to fix the path.
Check this sample Example code this might help you.
ASPX Code :
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>
HTTP Handler class Impliment in Img tag
</h1>
<h1>Id : 1</h1>
<img src="ImageHandler.ashx?id=1" alt="Dynamic Image" />
<h1>Id : 2</h1>
<img src="ImageHandler.ashx?id=2" alt="Dynamic Image" />
</div>
</form>
</body>
</html>
C# Examples (ImageHandler.ashx File) :
<%# WebHandler Language="C#" Class="ImageHandler" %>
using System;
using System.Web;
public class ImageHandler : IHttpHandler {
public void ProcessRequest (HttpContext context) {
//context.Response.ContentType = "text/plain";
//context.Response.Write("Hello World");
context.Response.ContentType = "image/jpeg";
if (context.Request.QueryString["id"] == "1")
{
context.Response.WriteFile("bamboo.jpg");
}
else
{
context.Response.WriteFile("palmtree.jpg");
}
}
public bool IsReusable {
get {
return false;
}
}
}
Here is live downloadable C# Examples and VB.Net Examples of this. Click Here...
I would like to know some of the strategy/practice you deal with to handle unhandled exceptions in ASP.NET MVC.
In short I want to avoid the yellow screen whenever any error happens and show a error consistent error message to the visitor.
I mean do you write a controller for this which shows the appropriate error page or you go some other way like writing an httpmodule and trapping the error at a global level.
Any inputs in this direction is appreciated.
Using the HandleError attribute is the way to go. Here is a small sample which I use to handle Ajax calls from JQuery, ExtJs, and others.
On your controller
public class DataController : Controller
{
[HandleError(ExceptionType = typeof(ArgumentException), View = "ErrorAjax")]
public void Foo(string x, string y)
{
if (String.IsNullorEmpty(x))
throw new ArgumentException("String cannot be empty!");
// Call your layers or whatever here
AnotherCall();
}
}
Then on your view (ErrorAjax). Notice it's strongly typed (HandleErrorInfo)
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<HandleErrorInfo>" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Sorry Dude!</title>
</head>
<body>
<div>
<!-- be creative here-->
Sorry, an error occurred while processing your request.
Action = <%= ViewData.Model.ActionName %>
Controller = <%= ViewData.Model.ControllerName %>
Message = <%= ViewData.Model.Exception.Message %>
</div>
</body>
</html>
A couple of gotchas
Check your web.config and make sure customErrors mode="On"
For starters, create the View under the Shared folder
Try the HandleError attribute.
Don't use the exception handling article that you linked to. It's an old article where they didn't have the HandleError attribute added in the framework. Use the HandleError attribute. It was added in preview 4.
The included script references, in particular jQuery, are being rendered after viewstate. Is there a way to get this in the < head>?
Page.ClientScript.RegisterClientScriptInclude("jQuery", "/scripts/jquery.js");
I am trying to register jquery.js in a user control's page load.
Thanks in advance!
P.S. If it can't be done (with ClientScript), anyone have an idea why they didn't build it in?
UPDATE
The main feature of the ClientScript manager I need is the ability to only include a script once. The control can appear many times on a page, but i only want one jQuery script include
to directly inlcude it in the HEAD:
HtmlGenericControl Include = new HtmlGenericControl("script");
Include.Attributes.Add("type", "text/javascript");
Include.Attributes.Add("src", sInclude);
this.Page.Header.Controls.Add(Include);
you would want to check to make sure its not there already before adding it.
I had this problem a while back, and I ended up not using RegisterClientScriptInclude.
I placed a placeholder in the header of the page, and added the script tag to the placeholder via a HtmlGenericControl.
I'll see if I can find my code and I'll edit my answer with it.
EDIT
I couldn't find my code, so I just re-created it:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<asp:PlaceHolder runat="server" ID="HeadPlaceHolder"></asp:PlaceHolder>
</head>
<body>
...
</body>
</html>
And the Code Behind:
protected void Page_Load(object sender, EventArgs e)
{
HeadPlaceHolder.Controls.Add(/* Your control here */);
}
Hey, old question, but maybe this is still of interest for someone.
I am creating a own UserControl with .net 3.5sp1, ran into the same problems. Following solution works for me.
This code is from the UserControl class:
protected void Page_Init( object sender, EventArgs e )
{
const string scriptKey = "UserControlScript";
if( !Page.ClientScript.IsClientScriptIncludeRegistered( Page.GetType(), scriptKey ) )
{
Page.ClientScript.RegisterClientScriptInclude( Page.GetType(), scriptKey, ResolveClientUrl("~/js/UserControl.js" ) );
}
}
I used Page_Init because I need to do some more initialization that has to be done before Page_Load of the nesting page is called.
It appears its not possible to use Page.ClientScript to add scripts to the header of the page.
Is there a quick and dirty way of using a query passed as follows:
domain.com/mypage.aspx/product/toycar/
I've done it before in PHP, but this needs to be done in page (in this instance).
--
I only have access to the aspx page and code behind, and have to work in asp.net 2 (i wish i was using 3.5)
quick and dirty:
public class ModuleRewriter : IHttpModule
{
public void Init(HttpApplication application)
{
application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
}
private void Application_BeginRequest(Object source, EventArgs e)
{
// The url will look like: http://domain.com/mypage.aspx/product/toycar/
// The module will rewrite it to: http://domain.com/mypage.aspx?product=toycar
HttpApplication application = source as HttpApplication;
string[] urlInfo = application.Request.RawUrl.ToString().Split('/');
if (urlInfo.Length > 2)
{
string page = urlInfo[urlInfo.Length - 3];
string action = urlInfo[urlInfo.Length - 2];
string id = urlInfo[urlInfo.Length - 1];
if (string.IsNullOrEmpty(page))
{
page = "default.aspx";
}
application.Server.Transfer(string.Format(
"~/{0}?{1}={2}", page, action, id));
}
}
public void Dispose()
{
}
}
web.config:
<httpModules>
<add name="ModuleRewriter" type="ModuleRewriter, MyWebApplication"/>
</httpModules>
and a test page:
<%# Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<%= Request["product"] %>
</div>
</form>
</body>
</html>
You might want to look into the ASP.NET System.Web.Routing namespace, which was added in .NET 3.5 SP1 I believe:
http://blogs.msdn.com/mikeormond/archive/2008/05/14/using-asp-net-routing-independent-of-mvc.aspx
http://msdn.microsoft.com/en-us/library/system.web.routing.aspx
You'd be able to get rid of the .aspx extension too.
This would involve making a custom HTTP Handler.
Check this
You've got a few options, but all of them require access to the web.config and a change to IIS to map all file extensions to the dotNet ISAPI dll:
Use MVC (like stackoverflow does,
notice the urls)
Use asp.net routing (new in 3.5)
Write your own http handler Massive guide from Microsoft here
Use the excellent urlrewriting.net which does just about everything perfectly including getting round some awkward authentication and image path problems.
Personally I used urlrewriting.net with good results.
Since you mention you don't have access to anything but the code behind and the page, the only thing I can think of is actually creating those dirs (if you have access to do that) and using a server.transfer page passing the value to your actual page in the folder above. Messy, but if you can't access the other stuff, your choices are limited.
In case you just want to read the path from within your .aspx:
Request.ServerVariables["PATH_INFO"]
To clarify:
he has only access to the aspx (+ codebehind) itself, so he must know how the query is, but it is not in the Request.QueryString because of the format. So the only way then is Request.ServerVariables["PATH_INFO"] (Request.RawUrl)