Developer Forum »
MVC 404
42 posts

It would seem that WAF currently triggers a 404 only if a route is not found and a node with the current URL address is not found.

If however, a route is found, but not a node with a correct Address is not found, Request.GetContent() defaults to the Site's start node, but does not return a 404.

I understand this behaviour because otherwise there would be no way of reaching routes that do not belong to a node.

Is there some way of detecting if a node with a corresponding Address was not found? Is there a property in place on Request somewhere? :)

I currently have the following "hack" in place:

 

if (site.StartNode.GetId() != content.NodeId || (localPath = requestContext.HttpContext.Request.Url.LocalPath) == "/" || localPath.Equals(WAFContext.GetUrl(content), StringComparison.OrdinalIgnoreCase)) page exists...

else not found...

 

 

And additionally:

 

static void WriteResponseFromRequest(string url, int errorCode)

{

HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);

 

using (MemoryStream memoryStream = new MemoryStream())

{

HttpResponse response = HttpContext.Current.Response; HttpWebResponse webResponse;

 

response.TrySkipIisCustomErrors = true;

 

try

{

webResponse = (HttpWebResponse)httpWebRequest.GetResponse();

}

 

catch (WebException e)

{

webResponse = (HttpWebResponse)e.Response;

}

 

Stream responseStream = webResponse.GetResponseStream();

 

byte[] buffer = new byte[8192]; int count;

 

do

{

count = responseStream.Read(buffer, 0, buffer.Length);

 

if (count != 0) memoryStream.Write(buffer, 0, count);

 

} while (count > 0);

 

response.StatusCode = errorCode;

response.StatusDescription = webResponse.StatusDescription;

 

response.BinaryWrite(memoryStream.ToArray());

}

}

 

static void NotFound(Site site)

{

var context = HttpContext.Current;

 

if (site.ShowUnfriendly404ErrorPage(context.Request)) return;

 

var application = context.ApplicationInstance;

 

switch (site.Friendly404ErrorPageUrl.LinkType)

{

case LinkType.InternalContent:

WriteResponseFromRequest(WAFContext.UrlFromRootToHost + site.Friendly404ErrorPageUrl.GetUrl() + "?Url=" + HttpUtility.UrlEncode(WAFContext.GetFullOriginalUrl()) + "&ErrorCode=404", 404);

application.Server.ClearError();

break;

 

case LinkType.ExternalAddress:

application.Response.Redirect(site.Friendly404ErrorPageUrl.GetUrl() + "?ErrorCode=404&Url=" + HttpUtility.UrlEncode(WAFContext.GetFullOriginalUrl()));

application.Server.ClearError();

break;

 

case LinkType.Email:

application.Response.Redirect(site.Friendly404ErrorPageUrl.GetUrl() + "?Body=" + HttpUtility.UrlEncode(site.Friendly404ErrorMessage));

application.Server.ClearError();

break;

 

case LinkType.Empty:

WAFContext.ReturnPage(site.GetFriendly404ErrorTitle(404), site.Friendly404ErrorMessage, false, true, 404);

application.Server.ClearError();

break;

}

 

application.Response.End();

}

181 posts

Hi!

We've looked into this, and we'll add a property on WAFRequest in an update soon. I'll update this thread when it's released.

We've set aside time in the development plan to look at how we can improve MVC support in Webnodes. We welcome all suggestions for improvements regarding our MVC support. Post it here in the forum, or send us an email! 

 

42 posts

Could it be possible to also add a method that automatically returns a 404 and ends the request? I extracted the additional code excerpt from the former post, from the WAF.dll (with some small modifications) :>

181 posts

You mean a method on WAFRequest? Could you explain why you would need that? Responding with a 404, and then ending the request in your own code is just a few lines.

42 posts

If a route that relates to a node does some checking and finds out that the page does indeed not exist, a 404 must be returned. Ideally, this behavour should follow Webnodes 404 behaviour, i.e. from what has been defined in the Webnodes GUI. Simply responsing with a 404 will not immitate this behaviour.

I think? :)

See static void NotFound(Site site) in the first post.

42 posts

Please tell me if any of what I'm trying to explain is still unclear. The issue can be demonstrated by loading the default MVC3 demo application, by first visiting e.g. http://localhost:63021/Article/an-article-1 and then by appending some random letters to the address: http://localhost:63021/Article/an-article-1test. The latter does not return a 404, but defaults to the frontpage. A route is found, no node with a matching address is found. The problem gets more serious when a friendly url solution is in place, in which case the Webnodes 404 error handling is completely defunct.

Another suggestion could be that GetContent() returns null if no matching node is found.

181 posts

Hi!

That explanation made it clearer what you meant. We'll look into this in detail and come up with a solution that have better 404 handling.

Today it is fairly simple to add your own 404 handling in for example a route handler when using a friendly url setup. We have to make sure we don't stop those possibilities, but at the same time have better 404 handling out of the box.

I don't think we want to return null from GetContent. That will have a wide range of implications for very little benefit IMO. 

 

31 posts

Hi,

I did some testing with a clean Webnodes MVC application, trying to get the built-in 404 handling to work (I'm referring to the Friendly404 options on the Site node). Did I understand it correctly that I would need to implement my own 404 route handling in order to get this to work?

If so, is there a property on the WAFRequest that I can check to see if the requested content was not found?

120 posts

Hi, the latest build in Webnodes addresses this issue!

1