November Happy Hour will be moved to Thursday December 5th.
November Happy Hour will be moved to Thursday December 5th.
Are you using any packages like BVN.NotFound handler. I remember of having it one of the CMS 11 projects where it will show 200 in network tab in case of 404 errors. Also any reason why you want to have 200 network tab for 404 errors.
I don't want a 200 error, I want to make sure the 404/500 error status code is passed along. Currently, since the error page I want to use exists in CMS. The web.config points to these pages, and at least the 404 error is sending a statusCode of 404, but the site is obviously not passing that status along to the browser.
Let me make sure I understand correctly. If you need error code passed on to browser, In that case I believe, you can remove any not found handlers (in your project like BVN etc).
public class ErrorPage : SitePage public virtual int StatusCode { get; set; } |
public class ErrorPageController : PageControllerBase<ErrorPage> if (currentPage != null) var code = (int)(HttpStatusCode)currentPage.StatusCode; return View(model); |
<httpErrors errorMode="Custom" existingResponse="Auto"> <remove statusCode="404" /> <error statusCode="404" path="/404-error" responseMode="ExecuteURL" /> </httpErrors> |
I have most of that code in and it is an improvement. However, when I actually type in an invalid URL it still just goes to the default browser 404 page, instead of routing to the NotFound page (/notfound). It also doesn't let me even view the page from the CMS admin view either.
public class ErrorPageController : PageControllerBase<ErrorPage>
{
public ActionResult Index(ErrorPage currentPage)
{
PageViewModel<ErrorPage> model = null;
if (currentPage != null)
{
model = PageViewModel.Create(currentPage);
PageViewModel.Create(currentPage);
}
// Validate that currentPage.StatusCode is a valid enum value before casting
// if (Enum.IsDefined(typeof(HttpStatusCode), currentPage.StatusCode))
// {
// Response.StatusCode = currentPage.StatusCode;
// }
// else
// {
// // Handle the case where currentPage.StatusCode is not a valid status code
// // You might log this issue and set a default status code
// Response.StatusCode = (int) HttpStatusCode.InternalServerError;
// }
var code = (int) (HttpStatusCode) currentPage.StatusCode;
Response.StatusCode = code;
return View(model);
}
}
[ContentType(
DisplayName = "Error Page",
GUID = "1286779b-d4cb-4053-96ba-68622cc796c1",
Description = "Used for various error messages")
]
public class ErrorPage : SitePageData
{
// Define properties here that you want to include on your error pages
// For example, a property for a custom error message
[CultureSpecific] public virtual ContentArea ErrorContentArea { get; set; }
public virtual int StatusCode { get; set; }
}
@using ErrorPage = Page.ErrorPage
@using EPiServer.Web.Mvc.Html
@model CMS.Ellsworth.ViewModels.PageViewModel<ErrorPage>
@if (Model.CurrentPage.DisplayPageTitle)
{
<div class="row header">
<div class="col-xs-12">
<h1>@Model.CurrentPage.PageTitle</h1>
</div>
</div>
}
@Html.PropertyFor(x => x.CurrentPage.ErrorContentArea)
<httpErrors errorMode="Custom" existingResponse="Auto">
<remove statusCode="404" />
<error statusCode="404" path="/not-found" responseMode="ExecuteURL" />
</httpErrors>
At this point I am assuming there is package like BVN which is handling your 404's , you might want to check and remove them to validate this. Also I assume you had created a page in CMS which is accessible at /not-found path.
Make a basic NotFoundController which can that serve up your 404Page
e.g.
public class NotFoundController : Controller
{
#region Fields
//private readonly ILanguagePreferenceResolver languagePreferenceResolver;
private readonly ISiteSettingsProvider settingsProvider;
#endregion
#region Constructors and Destructors
public NotFoundController()
{
// User service locator pattern as this class will be instantiated from BVNetwork library not from StructureMap
//languagePreferenceResolver = ServiceLocator.Current.GetInstance<ILanguagePreferenceResolver>();
settingsProvider = ServiceLocator.Current.GetInstance<ISiteSettingsProvider>();
}
#endregion
#region Public Methods
public ActionResult Index()
{
// set the response headers
Response.Headers["Server"] = string.Empty;
Response.StatusCode = 404;
if (Path.HasExtension(Request.RawUrl))
{
return new EmptyResult();
}
var loader = ServiceLocator.Current.GetInstance<IContentLoader>();
var urlRewriteContext = new UrlRewriteContext(new UrlBuilder(Request.RawUrl));
var currentCulture = urlRewriteContext.Language ?? ContentLanguage.PreferredCulture;
/*
if (!languagePreferenceResolver.IsValidLanguage(currentCulture.Name))
{
var browserLanguages = Request.UserLanguages?.ToList() ?? new List<string>();
var preferredLanguage = languagePreferenceResolver.PreferredLanguageBranch(browserLanguages);
currentCulture = new CultureInfo(preferredLanguage.LanguageID);
}
*/
ContentLanguage.PreferredCulture = currentCulture;
var error404Page = settingsProvider.Current?.Error404Page;
if (!ContentReference.IsNullOrEmpty(error404Page))
{
// Load 404 page content and pass to view
var notFoundPage = loader.Get<NotFoundPage>(
error404Page,
LanguageSelector.Fallback(ContentLanguage.PreferredCulture.Name, true));
Request.RequestContext.SetContentLink(error404Page);
if (notFoundPage != null)
{
return View(Constants.ViewPath.NotFoundPage, new NotFoundPageViewModel(notFoundPage));
}
}
return new EmptyResult();
}
#endregion
}
Your web.config should than look like
<httpErrors errorMode="Custom">
<remove statusCode="404" />
<error statusCode="404" path="/NotFound" responseMode="ExecuteURL" />
<remove statusCode="410" />
<error statusCode="410" path="/NotFound" responseMode="ExecuteURL" />
<remove statusCode="500" subStatusCode="-1" />
<error statusCode="500" path="/500.aspx" responseMode="ExecuteURL" />
</httpErrors>
Just for absolute completeness my Not Found Page (Your 404 Page) Controller than looks like
/// <summary>
/// Not Found Page Controller
/// </summary>
/// <seealso cref="NotFoundPage" />
public class NotFoundPageController : PageControllerBase<NotFoundPage>
{
#region Public Methods
/// <summary>
/// Indexes the specified current page.
/// </summary>
/// <param name="currentPage">The current page.</param>
/// <returns></returns>
public ActionResult Index(NotFoundPage currentPage)
{
var urlRewriteContext = new UrlRewriteContext(new UrlBuilder(Request.RawUrl));
var currentCulture = urlRewriteContext.Language;
ContentLanguage.PreferredCulture = currentCulture;
var currentculture = ContentLanguage.PreferredCulture;
var page = ServiceLocator.Current.GetInstance<IContentLoader>()
.Get<NotFoundPage>(currentPage.PageLink, currentculture);
// This removes the server from the response, it isn't handled by the URL rewriter.
Response.Headers["Server"] = string.Empty;
var viewModel = new NotFoundPageViewModel(page);
return View(viewModel);
}
#endregion
}
There are some issues with the code you provided, in the ErrorController.cs. I'm not sure what .Error404Page variable should be, since that specific one doesn't exist and I'm not sure where that is set.
I have a Optimizely CMS 11 + Commerce 13 website on .NET Framework 4.7.2. Currently there is a "NotFound" (404) and "Error" (500) pages created in the CMS that display a user-friendly 404 page, except due to this and the pre-existing configuration, anything that actually results in reaching that page like an invalid URL like http://localhost:5000/productproduct will still return a 200 status code in the Network dev tools. I have tried all documentation I've found so far but no luck, and I prefer to accomplish it as close to this method as possible.
Here is the web.config configuration - I have tried PassThrough, Replace, Auto - in the existingReponse.
NotFound.aspx - I know this displays when "Replace" is set as existingResponse, but this is the code there is - the onLoad was the logic for handling applying 404 error. (also tried
I turned on Error handling, but still the same issues.