Custom Error Page Display Asp.net - custom-error-pages

If something breaks in my code i was trying to show an custom error page so i have tried the following
1)placing the below in web.config file
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<customErrors mode="On" defaultRedirect= "Error.aspx">
</customErrors>
</system.web>
2)And tried placing the following in Global.asax.cs
protected void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
Server.ClearError();
Response.Redirect("Error.aspx");
}
3) i tried it having in page level like below
ErrorPage="~/Error.aspx"
None of them have worked , The main intention for me to show custom error page is when a value is retrieved from the database it should bind to the screen for the old records we don't have few elements so i thought of showing custom error message ,Please help me /suggest me ( i am using .net framework 4.5)

Related

Partial view not found exception with asp.net core in IIS only

We are having problems with partial views after migrating to .net 5. The main page will optionally render a custom partial view to allow per-customer customizations. After migrating we are unable to render these partial views. the error message is:
InvalidOperationException: The partial view ~/Resources/Customer/Views/File.cshtml was not found. The following locations were searched: ~/Resources/Customer/Views/File.cshtml
We know the path is valid because if we rename the file the page renders (without customizations). If we debug in visual studio the page renders as expected but in a deployed IIS server it fails. We suspect there is a permissions issue but we have been unable to find it. So far we haven't been able to find anything in google searches or SO
Here is a snippet where we handle the custom file:
// load file path from config
string url = configuration.OrderPageSetting["OrderInfoViewRenderFile"];
bool exists = false;
// determine the path
if (!string.IsNullOrWhiteSpace(url))
{
string _url = url;
if (_url.StartsWith("~/")) _url = _url.Substring(2);
else if (_url.StartsWith("/")) _url = _url.Substring(1);
exists = System.IO.File.Exists(System.IO.Path.Combine(Resource.SystemDirectory, _url));
}
// test for and render custom view
if (exists)
{
var data = new ViewDataDictionary<object>(new EmptyModelMetadataProvider(), new ModelStateDictionary());
data.Add("Order", order);
data.Add("Config", configuration);
await Html.RenderPartialAsync(url, data);
}
else
{
... default rendering ...
}
The application is hosted in a virtual directory with a dedicated application pool. This problem occurs without a web.config at the site level. On the same server, the prior .net framework version of the application works correctly.
here is the applications web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\myapp.dll" stdoutLogEnabled="false" hostingModel="InProcess" stdoutLogFile=".\logs\stdout">
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</location>
</configuration>
A co-worker found the solution the problem, the clue was in https://weblog.west-wind.com/posts/2019/Sep/30/Serving-ASPNET-Core-Web-Content-from-External-Folders
There were 2 changes required:
Add package: Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation
called extension to support runtime complication on the controllers/views:
services.AddControllersWithViews().AddRazorRuntimeCompilation(opt =>
{
opt.FileProviders.Add(
new PhysicalFileProvider(System.IO.Path.Combine(Environment.ContentRootPath, ""))
);
})
if you want to change where the dynamic compilation is supported, simply change the "" to the path where it is permitted.

Custom status code page with Windows Authentication

I've project in ASP NET Core 3.1 with Windows Authentication. I would like to use custom error code page.
This a basic example.
In HomeController :
[Route("/Error/401")]
public IActionResult StatusCode401()
{
HttpContext.Response.StatusCode = 401;
return View("ErrorUnauthorized");
}
But when I call StatusCode401 method, Windows prompt dialog (login, password) appears, if I cancel it, I see my custom view.
If I disable Windows Authentication, it's works fine.
How disable Windows prompt dialog when I use Windows Authentication ?
Thanks
You can open the web.config,
And then find the statusCode 401, change the responseModel from ExecuteURL to File
<system.webServer>
<httpErrors errorMode="Custom" >
<error statusCode="403" subStatusCode="0" prefixLanguageFilePath="" path="***" responseMode="ExecuteURL" />
<error statusCode="401" subStatusCode="2" prefixLanguageFilePath="" path="***" responseMode="File" />
....
</httpErrors>
</system.webServer>

MVC CustomError not found

I'm trying to debug in VS express 2013 with my MVC4 application.
In a view, I've added a nonsense link, such as link, but I don't see the intended View when I click on the link, I see the IIS page.
I did this by creating an ErrorController which is
public class ErrorController : Controller
{
public ActionResult Index()
{
return View();
}
}
My view remains as the default, I didn't update it.
And my webconfig is
<customErrors mode="On" defaultRedirect="~/Error">
</customErrors>
The routes are the default!
The IIS message is
HTTP Error 404.0 - Not Found
If I type in http://localhost:53258/error/ then I see the page, suggesting that the mapping is fine.
What have I done wrong?
Check for this in your web.config, and add it if you don't have it:
<httpErrors errorMode="Custom" existingResponse="PassThrough" />
Try updating your customErrors node to add this:
<error statusCode="404" redirect="~/Error" />
Thus, your custom errors section would look like:
<customErrors mode="On">
<error statusCode="404" redirect="~/Error" />
</customErrors>

StarterSTS FederationMetadata Generator configuration for asp.net mvc 4

How do i configure dynamic federation metadata generator http handler that comes with StarterSTS to work along with ASP.NET MVC 4, right now i got this configuration inside web.config on IIS 7 but browser returns 404 not found
<!-- handler to dynamically generate WS-Federation metadata -->
<location path="FederationMetadata/2007-06">
<system.webServer>
<handlers>
<add name="MetadataGenerator" path="FederationMetadata.xml" verb="GET" type="Thinktecture.IdentityServer.WSFedMetadataGenerator,Thinktecture" />
</handlers>
</system.webServer>
<system.web>
<httpHandlers>
<add path="FederationMetadata.xml" verb="GET" type="Thinktecture.IdentityServer.WSFedMetadataGenerator,Thinktecture" />
</httpHandlers>
</system.web>
</location>
404 Not found
https://localhost/website/FederationMetadata/2007-06/
Ok here is the truth it does not work. So here is what i did,
created a new asp.net mvc controller named it FederationMetadata
Copied the code to generate the federation metadata in the Index action method
Always point to https://<pc:name>/stsvirtualdirectoryname/FederationMetadata/ to get the federation metadata xml document
Code
if (STS.Configuration.Endpoints.WSFedMex)
{
EnsureInitialized();
var serializer = new MetadataSerializer();
var sb = new StringBuilder(512);
serializer.WriteMetadata(XmlWriter.Create(new StringWriter(sb),new XmlWriterSettings { OmitXmlDeclaration = true }), _entity);
return new ContentResult(){Content = sb.ToString(),ContentEncoding = Encoding.UTF8,ContentType = "text/xml"};
}
else
{
throw new HttpException(404, "Not found");
}

IIS Virtual Directory/Application & Forms authentication

I've setup and deployed a simple forms authentication website with membership using .NET 4.
I've created a virtual directory (now converted to "Application") in IIS7 and setup the web.config file in the virtual directory as follows:
<configuration>
<system.web>
<authorization>
<deny users="?">
</authorization>
</system.web>
<system.webServer>
<directoryBrowse enabled="true" />
</system.webServer>
</configuration>
Great! I browse to the virtual directory: ../mydomain/books/
and I'm automatically redirected to the login page specified by web.config in my root directory and the url path is placed as follows:
../Account/Login.aspx?ReturnUrl=%2fbooks
At this point, I login succesfully, but I am not redirected anywhere, and when I manually return to the directory, ../books, I'm sent back to the login page, where I'm already logged in?
So I'm confused about what my problem is! I should be successfully authenticated, and than redirected back to the directory, or at the very least be able to view it manually after I log in right?
Since I had to solve this myself, I thought I may as well post it for others in case their search brings them here.
This is everything you'll need to use Forms Authentication, allow your formatting to be exposed to anonymous users, pass credentials between an existing .Net (.aspx) web site and an MVC web application and redirect to a given url after login.
Use whatever pieces you are looking for.
Make sure your Virtual Directory/Virtual Application path for your .Net web application (.aspx) is outside of the Views directory. Also make sure you set up your Virtual Directory/Application in IIS.
I used Entity Framework and Identity with a SQLServer database to validate my users.
Your Virtual Application/Directory .Net (.aspx) web.config file needs to contain this:
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<!-- other stuff -->
<system.web>
<authentication mode="Forms">
<forms
loginUrl="login.aspx"
name=".AUTHCOOKIE"
protection="All"
path="/"
domain="your_domain.com"
enableCrossAppRedirects="true"
timeout="60">
</forms>
</authentication>
<authorization>
<deny users="?" />
<allow users="*" />
</authorization>
<machineKey
validationKey="your validation key"
decryptionKey="your decryption key"
validation="SHA1"
decryption="AES"
/>
<!-- other stuff -->
</system.web>
<location path="/path/to/your/site.css">
<system.web>
<authorization>
<allow users="?"></allow>
</authorization>
</system.web>
</location>
<!-- other stuff -->
</configuration>
Then, in the code behind your login.aspx page you'll need something like this:
protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)
{
string username = Login1.UserName;
string pwd = Login1.Password;
/* do your authentication here
connect to user store
get user identity
validate your user
etc
*/
if (user != null)
{
FormsAuthentication.SetAuthCookie(username, Login1.RememberMeSet);
System.Web.HttpCookie MyCookie = System.Web.Security.FormsAuthentication.GetAuthCookie(User.Identity.Name.ToString(), false);
MyCookie.Domain = "your_domain.com";
Response.AppendCookie(MyCookie);
Response.Redirect("~/path/to/your/index.aspx");
}
else
{
StatusText.Text = "Invalid username or password.";
LoginStatus.Visible = true;
}
}
Now, in your MVC applications web.config file add this:
<configuration>
<!-- other stuff -->
<system.web>
<authentication mode="Forms">
<forms
loginUrl="Account/Login"
name=".AUTHCOOKIE"
protection="All"
path="/"
domain="your_domain.com"
enableCrossAppRedirects="true"
timeout="30"/>
</authentication>
<authorization>
<deny users="?"/>
<allow users="*"/>
</authorization>
<machineKey
validationKey="your validation key"
decryptionKey="your decryption key"
validation="SHA1"
decryption="AES"
/>
<!-- other stuff -->
</system.web>
<location path="/path/to/your/site.css">
<system.web>
<authorization>
<allow users="?"></allow>
</authorization>
</system.web>
</location>
<!-- other stuff -->
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<remove name="FormsAuthenticationModule"/>
<add name="FormsAuthenticationModule" type="System.Web.Security.FormsAuthenticationModule"/>
<remove name="UrlAuthorization"/>
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"/>
</modules>
</system.webServer>
<!-- other stuff -->
</configuration>
In your MVC AccountController Login method should look something like this:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
/* do your authentication here
connect to user store
get user identity
validate your user
etc
*/
if (user != null)
{
await SignInAsync(user, model.RememberMe);
FormsAuthentication.SetAuthCookie(model.Email, model.RememberMe);
System.Web.HttpCookie MyCookie = System.Web.Security.FormsAuthentication.GetAuthCookie(User.Identity.Name.ToString(), false);
MyCookie.Domain = "your_domain.com";
Response.AppendCookie(MyCookie);
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "Invalid username or password.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Finally, your MVC AccountController log off method is this:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
AuthenticationManager.SignOut();
FormsAuthentication.SignOut();
return RedirectToAction("Login", "Account");
}
You need to add code to redirect to the "ReturnUrl" URL noted in the query string from within your Login page after you login.