Asp net ошибка 403

I have downloaded the MVC Music Store ASP.NET application at location C:UsersDEVESHDesktopProjectsMvcMusicStore-v3.0MvcMusicStore-CompletedMvcMusicStore
and added the website on IIS at the same location. I have also given permission to IIS_IUSRS, but when I run localhost I am getting the error:

HTTP Error 403.14 — Forbidden The Web server is configured to not list the contents of this directory.

I have googled it, but have not found a fix. What I am doing wrong?

Jon Schneider's user avatar

Jon Schneider

25.5k23 gold badges140 silver badges169 bronze badges

asked Jul 13, 2013 at 14:42

F11's user avatar

1

I came across this error because I had the wrong .NET version (v2.0 instead of v4.0) configured on the web site application pool. I fixed it this way on Windows Server 2008 R2 and IIS 7. I’m pretty sure the instructions apply to Windows Server 2012 and IIS 8 as well:

  • Press keys Windows+R to open the Run dialog, type inetmgr and then click OK. This opens the IIS Manager.
  • In the left treeview, locate the Sites node and find the Default Web Site node under it (or the name of the site where the error message appears).
  • Right-click the node and select Manage web site -> Advanced settings…. Note the name of the value Application pool. Close this dialog.
  • In the treeview to the left, locate and select the node Application pools.
  • In the list to the right, locate the Application pool with the same name as the one you noted in the web site settings. Right-click it and select Advanced settings…
  • Make sure that the .NET Framework version value is v4.0. Click OK.

This doesn’t apply if you’re running an older site that actually should have .NET v2.0, of course :)

answered Feb 17, 2014 at 20:12

Daniel Persson's user avatar

Daniel PerssonDaniel Persson

2,1711 gold badge17 silver badges24 bronze badges

7

In my case ASP.NET not registered on server. try to execute this in command prompt:

Windows 32bit

%windir%Microsoft.NETFrameworkv4.0.30319aspnet_regiis.exe -ir

Windows 64bit

%windir%Microsoft.NETFramework64v4.0.30319aspnet_regiis.exe -ir 

answered Jul 4, 2016 at 8:33

Ruslan_K's user avatar

Ruslan_KRuslan_K

4137 silver badges23 bronze badges

4

Just in case if anyone reached here looking for solution, here is how i resolved it. By mistake I deleted all files from my server ( bin directory ) but when i recopied all files i missed App_global.asax.dll and App_global.asax.compiled files. Because these files were missing IIS was giving me this error

403 - Forbidden: Access is denied.

As soon as i added these files, it started working perfectly fine.

answered Aug 13, 2014 at 0:46

ATHER's user avatar

ATHERATHER

3,2065 gold badges39 silver badges63 bronze badges

0

I resolved this issue by correcting an error with my Global.asax file arrangement. I had copied across the files from another project and failed to embed the Global.asax.cs within the Global.asax file (both files previously existed at the same level).

Global.asax arrangement

answered Aug 24, 2015 at 9:51

Luke Zaparaniuk's user avatar

1

In my case when I browsed to
site5.com
I got the following error.

HTTP Error 403.14 — Forbidden
The Web server is configured to not list the contents of this directory.

Most likely causes:
A default document is not configured for the requested URL, and directory browsing is not enabled on the server.

And then when I browsed to

site5.com/home/index

I was met with

HTTP Error 404.0 — Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.

Most likely causes:
The directory or file specified does not exist on the Web server.
The URL contains a typographical error.
A custom filter or module, such as URLScan, restricts access to the file.

All that I did is installed the feature in IIS ASP.NET 4.8 as shown below.

enter image description here

answered Feb 22, 2020 at 10:09

VivekDev's user avatar

VivekDevVivekDev

19.8k26 gold badges128 silver badges199 bronze badges

I was using ASP.NET 4.5 MVC application on IIS 7. My fix was to set runallmanagedmodule to true.

<system.webServer>
            <modules runAllManagedModulesForAllRequests="true" />
</system.webServer>

or If you have other modules, you may want to add them inside the module tag.

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
             <add name="ErrorLogWeb" type="Elmah.ErrorLogModule, Elmah" preCondition="managedHandler" />
             ...
    </modules>
</system.webServer>

IIS Modules Overview : The Official Microsoft IIS Site

answered Apr 21, 2017 at 14:58

Priyank Agarwal's user avatar

0

I have encountered similar myself before for 2 reasons;
1. MVC is not installed.
2. The url routing module is not registered (this varies by machine in my workplace for a reason I cannot fully explain — it is not always registered at a system level ), try registering it in the application web.config:

<system.web> 
      ... 
      <httpModules> 
         ... 
         <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> 
      </httpModules>
   </system.web>

Edit: I forgot to add the location for iis 7+:

<system.webServer> 

      <modules> 
         ... 
         <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> 
      </modules>
</system.webServer>

answered Jul 13, 2013 at 15:37

David Bennington's user avatar

This error can happen when, in IIS Manager, the ASP.NET MVC site is pointed to the wrong directory.

In my case, I inadvertently had the site pointed to the solution directory instead of the child project directory. That is, I had the site’s Physical path set to

C:devMySolution

instead of

C:devMySolutionMyProject.

Specific steps to fix this:

  1. Open IIS Manager (Start > Run > inetmgr);
  2. In IIS Manager, in the left pane, expand Sites;
  3. Under Sites, left-click the ASP.NET MVC website;
  4. In the right pane, click Basic Settings…;
  5. In the Edit Site dialog, change the Physical path to the project directory.
  6. Click OK.

answered Jul 10, 2017 at 15:06

Jon Schneider's user avatar

Jon SchneiderJon Schneider

25.5k23 gold badges140 silver badges169 bronze badges

This error occurs when the application cannot startup.
So the cause can be anything that prevents your application to start.

  • Wrong connection string
  • Wrong IIS directory permissions
  • An exception thrown in your Application_Start() function
  • IOC Container initialization error
  • IIS ASP.NET registration errors
  • Missing DLL in your bin folder
  • etc…

answered Dec 15, 2016 at 16:08

Huseyin Yagli's user avatar

Huseyin YagliHuseyin Yagli

9,8166 gold badges41 silver badges50 bronze badges

I faced a similar (but not identical) issue.

I had to go to to Turn Windows features on or off in Control Panel and add ASP.NET 3.5 and 4.7:
enter image description here

Then it worked for me.

answered May 12, 2020 at 20:09

EJoshuaS - Stand with Ukraine's user avatar

0

I’ve just had the same problem, but my fix was that the Routing was not configured in the Global.asax.cs file. I’m using Bootstrapper and Castle Windsor, so to resolve this problem I added the following code to Global.asax.cs:

public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            Bootstrapper.IncludingOnly.Assembly(Assembly.GetAssembly(typeof(WindsorRegistration)))
                .With
                .Windsor()
                .With
                .StartupTasks()
                .Start();
        }
    }

Obviously if you are using the basic MVC then you will need to reference the RouteConfig file in the AppStart folder instead:

public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
    }

answered Oct 21, 2015 at 13:47

John's user avatar

JohnJohn

1,26816 silver badges25 bronze badges

In my case, i had multiple projects but i had not defined the starting Project.
So this error was generating.
After defining the startUp project solved the issue.

answered Jan 7, 2016 at 15:01

rns's user avatar

rnsrns

1432 silver badges7 bronze badges

0

I had this error after creating an empty ASP.Net application in Visual Studio. As soon as I added a file index.html to the main solution, it worked. So in my case, I just needed to add a file to the root of the project folder.

answered Jan 4, 2017 at 15:10

live-love's user avatar

live-lovelive-love

48k22 gold badges234 silver badges201 bronze badges

Check this also:

This problem occurs because the Web site does not have the Directory Browsing feature enabled, and the default document is not configured. To resolve this problem, use one of the following methods:

  • Method 1: Enable the Directory Browsing feature in IIS (Recommended)
  • Method 2: Add a default document Method
  • Method 3: Enable the Directory Browsing feature in IIS Express

LINK : https://support.microsoft.com/en-us/kb/942062

answered Nov 10, 2016 at 10:23

Bino's user avatar

BinoBino

69414 silver badges22 bronze badges

2

If project is a ASP.net MVC project it would be about routing.
In my case I changed default routing values:

routes.MapRoute(
           "Default",                                              
           "{controller}/{action}/{id}",                           
           new { controller = "Home", action = "Index", id = "" }  
       );

I changed my code accidentally to:

routes.MapRoute(
               "Default",                                              
               "{controller}/{action}/{JobID}",                           
               new { controller = "Home", action = "Index", id = "" }  
           );

Thats I only changed «id» to «JobId» and default route can not be find.

answered May 9, 2016 at 14:55

Ahmet Arslan's user avatar

Ahmet ArslanAhmet Arslan

5,2902 gold badges33 silver badges35 bronze badges

In my case index.aspx file was not created by default and after adding another web form i did not set the form as start page …After setting the page as start page my issue get resolved .
So right click a web form and set the form as start page
:)

answered May 12, 2017 at 17:08

AtiKa Bhatti's user avatar

IUSR permissions use on a folder if not under inetpub/wwwroot will be solution for some.

answered Feb 20, 2018 at 22:42

Tom Stickel's user avatar

Tom StickelTom Stickel

19.5k6 gold badges111 silver badges113 bronze badges

In my case, I had to disable ‘Exclude files from the App_Data folder’ in my publish profile to deploy the App_Data folder with my XML documentation (XmlDocument.xml). That got rid of the 403.14.

answered Jan 5, 2018 at 21:06

Sujay Paranjape's user avatar

in my case:
1. in IIS Manager, in left tree, left click the computer name, in right dialog click ISAPI and CGT limitation, in open dialog, select ASP.NET v4.0.30319 and select enable. There is two ASP.Net v4.0, one for 32bit, another for 64 bit. select depending on your OS bit.
2. in left tree select app pool, in right dialog, select the app pool your website used. double click that pool, in open dialog, .net framke item select .net framework v.4.0.30319. and pipe..item select integate.
Maybe there is some wrong translation above because my OS is not English version.

answered Jan 26, 2018 at 0:33

Penny's user avatar

PennyPenny

5961 gold badge6 silver badges15 bronze badges

In case anyone comes across this for a project other than MVC:

My project was a WCF project, which runs off .svc files—no default document. As a result I got a 403.14 error at myhost.com/ but as soon as I added a baseAddress path from my web.config file (ex. myhost.com/mybaseaddresspath.svc I got a webpage.

answered Feb 5, 2019 at 17:38

codeMonkey's user avatar

codeMonkeycodeMonkey

4,0532 gold badges31 silver badges49 bronze badges

My colleagues made a URL Rewrite rule, which reduced all URLs to a StaticFileHandler; mapped to a file path at the root of my Application physical folder.

(i.e. an over-aggressive URL rewrite means that my Controllers/Actions were not working)

Check your applications’ URL Rewrite rules to confirm they do what you expect.

answered May 9, 2019 at 23:44

Nate Anderson's user avatar

Nate AndersonNate Anderson

17.8k18 gold badges99 silver badges133 bronze badges

I faced the same issue while developing Business Central application.
Open Business Central Application and Edit Web Client Base URL
under Client Services.
You can enter http://localhost:8080/YourWebServerInstance/

enter image description here

answered Sep 19, 2022 at 19:03

Meli's user avatar

MeliMeli

314 bronze badges

I faced similar issue. My controller name was documents. It manages uploaded documents. It was working fine and started showing this error after completion of code. The mistake I did is — Created a folder ‘Documents’ to save the uploaded files. So controller name and folder name were same — which made the issue.

answered Jan 16, 2019 at 11:59

user10922241's user avatar

0

  • Remove From My Forums
  • Question

  • User1255309776 posted

    Hi,

    I published my project ForOffer to web hosting server using Web deployment method via Visual Studio 2017. I’ve entered all server details and publish was successful. (see

    https://prnt.sc/n1tlmb) .from my side (in Visual Studio)

    But when it opens the page error : 403 Forbidden comes. What might cause this? What I need to check and edit before publishing?

Answers

  • User1255309776 posted

    It finally worked. The problem was that hosting provided didn’t give me the full server name (with port), the server name they gave me today included a port number which helped to connect to database.

    Thank you guys for all your comments and info.

    • Marked as answer by

      Thursday, October 7, 2021 12:00 AM

HTTP Error 403.4 — Forbidden is an error that occurs when a client tries to access a website or web application and the server returns a response indicating that the client doesn’t have sufficient authorization to view the content. This error is typically encountered when SSL (Secure Sockets Layer) is enabled on the website, and the client is trying to access the site without using the secure HTTPS protocol. In this scenario, the server returns a 403.4 error to indicate that the client needs to use the secure connection to access the content.

Method 1: Enable Directory Browsing

To fix the HTTP Error 403.4 — Forbidden in Asp.Net, you can enable directory browsing. Here are the steps to do it:

  1. Open the IIS Manager.
  2. Click on the website or application you want to enable directory browsing for.
  3. Double-click on «Directory Browsing» in the Features View.
  4. Click «Enable» in the Actions pane.

Alternatively, you can enable directory browsing programmatically in your Asp.Net application by adding the following code to your web.config file:

<system.webServer>
  <directoryBrowse enabled="true" />
</system.webServer>

This will enable directory browsing for your entire application. If you only want to enable it for a specific directory, you can add the following code to your web.config file:

<location path="DirectoryName">
  <system.webServer>
    <directoryBrowse enabled="true" />
  </system.webServer>
</location>

Replace «DirectoryName» with the name of the directory you want to enable directory browsing for.

You can also customize the directory browsing page by adding the following code to your web.config file:

<system.webServer>
  <directoryBrowse enabled="true">
    <mimeMap fileExtension=".json" mimeType="application/json" />
  </directoryBrowse>
</system.webServer>

This will add a custom MIME type for JSON files in the directory browsing page.

Enabling directory browsing can be a quick and easy solution to the HTTP Error 403.4 — Forbidden in Asp.Net.

Method 2: Bind the SSL Certificate to the Web Site

To fix HTTP Error 403.4 — Forbidden in Asp.Net, you can bind the SSL certificate to the web site. Here are the steps to do it:

  1. Open IIS Manager and select the website that you want to bind the SSL certificate to.
  2. Click on «Bindings» in the right-hand panel.
  3. Click «Add» to add a new binding.
  4. Select «https» as the type and select the SSL certificate that you want to bind to the website.
  5. Click «OK» to save the binding.

Here’s an example code that you can use to bind the SSL certificate to the web site programmatically:

using (ServerManager serverManager = new ServerManager())
{
    Site site = serverManager.Sites["YourSiteName"];
    Binding binding = site.Bindings.CreateElement("binding");
    binding.Protocol = "https";
    binding.BindingInformation = "*:443:";
    binding.CertificateHash = "YourCertificateHash";
    site.Bindings.Add(binding);
    serverManager.CommitChanges();
}

In the code above, replace «YourSiteName» with the name of your website and «YourCertificateHash» with the hash of your SSL certificate.

This should fix the HTTP Error 403.4 — Forbidden issue in Asp.Net.

Method 3: Update the Web.Config File

To fix the HTTP Error 403.4 — Forbidden in Asp.Net, you can update the Web.Config file. Here are the steps:

  1. Open the Web.Config file in your project.
  2. Add the following code inside the <system.webServer> section:
<security>
  <requestFiltering>
    <verbs allowUnlisted="false">
      <add verb="GET" allowed="true" />
      <add verb="POST" allowed="true" />
    </verbs>
  </requestFiltering>
</security>

This code allows GET and POST requests, which are commonly used in web applications.

  1. Save the Web.Config file and rebuild your project.

With these steps, you should be able to fix the HTTP Error 403.4 — Forbidden in Asp.Net.

In previous article, we have discussed about how to fix error 404 in Asp.net MVC and also few error when deploying Asp.net Core application.

In this article, there is other common error that you can find when you deployed your Asp.net, sometimes you will see 403 Forbidden Error message. The full error message like below:

How to Solve 403 Error

Few reason that might cause 403 error. The following are steps to check it

1. Check your .NET Framework, make sure that you are using correct .NET Framework. In our example, we are using 4.6.1. So, on your web.config file, it is like below:

2. If you host your site with us, we are using Plesk control panel and you can easily change your .NET version on your control panel. Just go to “Hosting Settings” on your Plesk Control panel as you can see below:

3. Click Hosting Settings on your control panel, you can check your Asp.net framework version as shown below. For example if still using .net 3.5 framework, then you need to switch it to .net 4.7 or higher. Although you can’t see option like 4.6 or 4.8 or higher version, we have installed latest .NET on the server.

4. You can now set the version which you expect, click Apply and then OK. In our example, we set it to 4.7.2 version, save it and it started working.

Conclusion

We hope above article can help you to fix your issue. If still not working, there are other possibilities, for example you need to check your default page, make sure you have setup it correctly.

In case you are looking for Asp.net hosting support, you can always visit our site directly. We have support latest Asp.net version on our hosting environment. Please always feel free to email us if you have any questions.

Andriy Kravets is writer and experience .NET developer and like .NET for regular development. He likes to build cross-platform libraries/software with .NET.

Обработка ошибок

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7

Последнее обновление: 06.11.2019

Ошибки в приложении можно условно разделить на два типа: исключения, которые возникают в процессе выполнения кода (например, деление на 0), и
стандартные ошибки протокола HTTP (например, ошибка 404).

Обычные исключения могут быть полезны для разработчика в процессе создания приложения, но простые пользователи не должны будут их видеть.

UseDeveloperExceptionPage

Если мы создаем проект ASP.NET Core, например, по типу Empty (да и в других типах проектов), то в классе Startup мы можем найти в начале метода Configure() следующие строки:

if (env.IsDevelopment())
{
	app.UseDeveloperExceptionPage();
}

Если приложение находится в состоянии разработки, то с помощью middleware app.UseDeveloperExceptionPage() приложение перехватывает исключения и
выводит информацию о них разработчику.

Например, изменим класс Startup следующим образом:

public class Startup
{
	public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
	{
		if (env.IsDevelopment())
		{
			app.UseDeveloperExceptionPage();
		}
		app.Run(async (context) =>
		{
			int x = 0;
			int y = 8 / x;
			await context.Response.WriteAsync($"Result = {y}");
		});
	}
}

В middleware app.Run симулируется генерация исключения при делении ноль. И если мы запустим проект, то в браузере мы увидим
информацию об исключении:

Обработка исключений в ASP.NET Core

Этой информации достаточно, чтобы определить где именно в коде произошло исключение.

Теперь посмотрим, как все это будет выглядеть для простого пользователя. Для этого изменим метод Configure:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
	env.EnvironmentName = "Production";
	if (env.IsDevelopment())
	{
		app.UseDeveloperExceptionPage();
	}
	app.Run(async (context) =>
	{
		int x = 0;
		int y = 8 / x;
		await context.Response.WriteAsync($"Result = {y}");
	});
}

Выражение env.EnvironmentName = "Production"; устанавливает режим развертывания вместо режима разработки. В этом случае выражение if (env.IsDevelopment()) будет возвращать false, и мы увидим в браузере что-то наподобие «HTTP ERROR 500»

HTTP ERROR 500 в ASP.NET Core

UseExceptionHandler

Это не самая лучшая ситуация, и нередко все-таки возникает необходимость дать пользователям некоторую информацию о том, что же все-таки произошло. Либо потребуется как-то обработать данную ситуацию.
Для этих целей можно использовать еще один встроенный middleware в виде метода UseExceptionHandler(). Он перенаправляет
при возникновении исключения на некоторый адрес и позволяет обработать исключение. Например, изменим метод Configure следующим образом:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
	env.EnvironmentName = "Production";
	
	if (env.IsDevelopment())
	{
		app.UseDeveloperExceptionPage();
	}
	else
	{
		app.UseExceptionHandler("/error");
	}
	
	app.Map("/error", ap => ap.Run(async context =>
	{
		await context.Response.WriteAsync("DivideByZeroException occured!");
	}));
	
	app.Run(async (context) =>
	{
		int x = 0;
		int y = 8 / x;
		await context.Response.WriteAsync($"Result = {y}");
	});
}

Метод app.UseExceptionHandler("/error"); перенаправляет при возникновении ошибки на адрес «/error».

Для обработки пути по определенному адресу здесь использовался метод app.Map(). В итоге при возникновении исключения будет срабатывать делегат
из метода app.Map.

Error Handling in ASP.NET Core

Следует учитывать, что оба middleware — app.UseDeveloperExceptionPage() и app.UseExceptionHandler()
следует помещать ближе к началу конвейера middleware.

Обработка ошибок HTTP

В отличие от исключений стандартный функционал проекта ASP.NET Core почти никак не обрабатывает ошибки HTTP, например, в случае если ресурс не найден.
При обращении к несуществующему ресурсу мы увидим в браузере пустую страницу, и только через консоль веб-браузера мы сможем увидеть статусный код.
Но с помощью компонента StatusCodePagesMiddleware можно добавить в проект отправку информации о статусном коде.
Для этого добавим в метод Configure() класса Startup вызов app.UseStatusCodePages():

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
	if (env.IsDevelopment())
	{
		app.UseDeveloperExceptionPage();
	}
	
	// обработка ошибок HTTP
	app.UseStatusCodePages();
	
	app.Map("/hello", ap => ap.Run(async (context) =>
	{
		await context.Response.WriteAsync($"Hello ASP.NET Core");
	}));
}

Здесь мы можем обращаться только по адресу «/hello». При обращении ко всем остальным адресам браузер отобразит базовую информацию об ошибке:

UseStatusCodePages в ASP.NET Core

Данный метод позволяет настроить отправляемое пользователю сообщение. В частности, мы можем изменить вызов метода так:

app.UseStatusCodePages("text/plain", "Error. Status code : {0}");

В качестве первого параметра указывается MIME-тип ответа, а в качестве второго — собственно то сообщение, которое увидит пользователь. В сообщение мы можем
передать код ошибки через плейсхолдер «{0}».

Вместо метода app.UseStatusCodePages() мы также можем использовать еще пару других, которые также обрабатываю ошибки HTTP.

С помощью метода app.UseStatusCodePagesWithRedirects() можно выполнить переадресацию на определенный метод, который непосредственно обработает статусный код:

app.UseStatusCodePagesWithRedirects("/error?code={0}");

Здесь будет идти перенаправление по адресу «/error?code={0}». В качестве параметра через плейсхолдер «{0}» будет передаваться статусный код
ошибки.

Но теперь при обращении к несуществующему ресурсу клиент получит статусный код 302 / Found. То есть формально несуществующий ресурс будет существовать, просто статусный код 302
будет указывать, что ресурс перемещен на другое место — по пути «/error/404».

Подобное поведение может быть неудобно, особенно с точки зрения поисковой индексации, и в этом случае мы можем применить другой метод
app.UseStatusCodePagesWithReExecute():

app.UseStatusCodePagesWithReExecute("/error", "?code={0}");

Первый параметр метода указывает на путь перенаправления, а второй задает параметры строки запроса, которые будут передаваться при перенаправлении.
Вместо плейсхолдера {0} опять же будет передаваться статусный код ошибки. Формально мы получим тот же ответ, так как так же будет идти перенаправление на путь «/error?code=404». Но теперь браузер получит оригинальный статусный код 404.

Пример использования:

public void Configure(IApplicationBuilder app)
{
	// обработка ошибок HTTP
	app.UseStatusCodePagesWithReExecute("/error", "?code={0}");

	app.Map("/error", ap => ap.Run(async context =>
	{
		await context.Response.WriteAsync($"Err: {context.Request.Query["code"]}");
	}));

	app.Map("/hello", ap => ap.Run(async (context) =>
	{
		await context.Response.WriteAsync($"Hello ASP.NET Core");
	}));
}

Настройка обработки ошибок в web.config

Еще один способ обработки кодов ошибок представляет собой определение и настройка в файле конфигурации web.config элемента
httpErrors. Этот способ в принципе использовался и в других версиях ASP.NET.
В ASP.NET Core он также доступен, однако имеет очень ограниченное действие. В частности, мы его можем использовать только при развертывании на IIS, а также не можем использовать ряд настроек.

Итак, добавим в корень проекта новый элемент Web Configurarion File, который естественно назовем web.config:

Обработка ошибок в web.config

Изменим его следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <system.webServer>
	<httpErrors errorMode="Custom" existingResponse="Replace">
      <remove statusCode="404"/>
	  <remove statusCode="403"/>
      <error statusCode="404" path="404.html" responseMode="File"/>
      <error statusCode="403" path="403.html" responseMode="File"/>
	</httpErrors>
   
    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
    </handlers>
    <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".logsstdout" forwardWindowsAuthToken="false"/>
  </system.webServer>
</configuration>

Также для обработки ошибок добавим в корень проекта новый файл 404.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Ошибка 404</title>
</head>
<body>
    <h1>Ошибка 404</h1>
    <h2>Ресурс не найден!</h2>
</body>
</html>

По аналогии можно добавить файл 403.html для ошибки 403.

Итак, элемент httpErrors имеет ряд настроек. Для тестирования настроек локально, необходимо установить атрибут errorMode="Custom".
Если тестирование необязательно, и приложение уже развернуто для использования, то можно установить значение errorMode="DetailedLocalOnly".

Значение existingResponse="Replace" позволит отобразить ошибку по оригинальному запрошенному пути без переадресации.

Внутри элемента httpErrors с помощью отдельных элементов error устанавливается обработка ошибок. Атрибут statusCode
задает статусный код, атрибут path — адрес url, который будет вызываться, а атрибут responseMode указывает, как будет обрабатываться ответ вызванному url.
Атрибут responseMode имеет значение File, что позволяет рассматривать адрес url из атрибута path как статическую страницу и использовать ее в качестве ответа

Настройки элемента httpErrors могут наследоваться с других уровней, например, от файла конфигурации machine.config. И чтобы удалить
все унаследованные настройки, применяется элемент <clear />. Чтобы удалить настройки для отдельных ошибок, применяется элемент
<remove />.

Для тестирования используем следующий класс Startup:

public class Startup
{
	public void Configure(IApplicationBuilder app)
	{
		app.Map("/hello", ap => ap.Run(async (context) =>
		{
			await context.Response.WriteAsync($"Hello ASP.NET Core");
		}));
	}
}

И после обращения к несуществующему ресурсу в приложении отобразится содержимое из файла 404.html.

Настройка обработки ошибок в web.config в ASP.NET Core

A brief introduction of Problem details

If you have developed HTTP APIs, I’m sure that many times you have had the need to define new error response formats for HTTP APIs to return to your clients. The most common way to do this is using HTTP Status Codes but sometimes is not sufficient to communicate enough information to the clients. For example, imagine a banking HTTP API that allows customers to make online transactions and this call returns Forbidden (403) response telling the client that the customer isn’t allowed to make this transaction, but why? Maybe the customer doesn’t have enough credit? or he has a maximum limit of money to transfer?

To provide additional information to our clients we would need to extend the response body with some kind of document (JSON or XML). The problem I’ve seen in many HTTP APIs is that usually these documents are not the same. It’s very frustating for a client that consumes many HTTP APIs because there isn’t a standard way to deal with these errors and it would need to implement different ways to work with them.

Due to the need to standarize an error response format for HTTP APIs, the Internet Engineering Task Force (IETF) published in March 2016 a document that defines a “problem details” as a way to carry machine-readable details of errors in a HTTP response to avoid the need to define new error response formats for HTTP APIs (Not reinvent the wheel).

Let me show you an example of HTTP response of JSON problem details

HTTP/1.1 403 Forbidden
Content-Type: application/problem+json
Content-Language: en

{
    "type": "https://example.com/probs/out-of-credit",
    "title": "You do not have enough credit.",
    "detail": "Your current balance is 30, but that costs 50.",
    "instance": "/account/12345/msgs/abc",
    "balance": 30,
    "accounts": ["/account/12345","/account/67890"],
    "status": 403
}

The format of the message is application/problem+json media type (It could be application/problem+xml also) and we have several members in the response body:

  • type (string): URI that identifies the problem detail type. In this case “out-of-credit”.
  • title (string): A short human-readable summary about the problem.
  • detail (string): A human-readable explanation about the problem.
  • status (number): HTTP Status Code.
  • instance (string): A URI reference that identifies the specific occurrence of the problem.

We can extend the problem details object with additional members, for example the previous message defines two members “balance” and “accounts” to communicate additional information to the client.

Problem details in ASP.NET Core 2.1

When ASP.NET Core 2.1 came out, the ASP.NET Core team added support for problem details. The class that represents a problem details object is ProblemDetails

An example of use:

[HttpPost]
public ActionResult Transfer()
{
    try
    {
        /// Make a transfer
    }
    catch (OutOfCreditException ex)
    {
        var problemDetails = new ProblemDetails
        {
            Status = StatusCodes.Status403Forbidden,
            Type = "https://example.com/probs/out-of-credit",
            Title = "You do not have enough credit.",
            Detail = "Your current balance is 30, but that costs 50.",
            Instance = HttpContext.Request.Path
        };

        return new ObjectResult(problemDetails)
        {
            ContentTypes = { "application/problem+json" },
            StatusCode = 403,
        };
    }

    return Ok();
}

Problem Details 1

We alse have the ValidationProblemDetails class for validation errors. This class inherits from ProblemDetails and you can see an example in the following code:

[HttpPost]
public ActionResult Transfer(TransferInfo model)
{
    if (!ModelState.IsValid)
    {
        var problemDetails = new ValidationProblemDetails(ModelState);

        return new ObjectResult(problemDetails)
        {
            ContentTypes = { "application/problem+json" },
            StatusCode = 403,
        };
    }

    return Ok();
}

Problem Details 2

The two previous examples have the same problem: They are polluting our controllers (Put your controllers on a diet). IMHO controllers act as mediators: receive the request from the client, transform into a command, send it and response to the client. Let’s see how to move these validations out of controllers into a centralized place.

Model validations

For model validations we need to configure ApiBehaviorOptions in our ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services
        .AddMvc()
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    services.Configure<ApiBehaviorOptions>(options =>
    {
        options.InvalidModelStateResponseFactory = context =>
        {
            var problemDetails = new ValidationProblemDetails(context.ModelState)
            {
                Instance = context.HttpContext.Request.Path,
                Status = StatusCodes.Status400BadRequest,
                Type = $"https://httpstatuses.com/400",
                Detail = ApiConstants.Messages.ModelStateValidation
            };
            return new BadRequestObjectResult(problemDetails)
            {
                ContentTypes =
                {
                    ApiConstants.ContentTypes.ProblemJson,
                    ApiConstants.ContentTypes.ProblemXml
                }
            };
        };
    });
}

We have to remark on two things:

  • The order in which you register the services matter, you must register AddMvc() before configure ApiBehaviorOptions otherwise you won’t see the correct response.

Problem Details 3

  • Your controllers must be decorated with the [ApiController] attribute:
[Route("api/[controller]")]
[ApiController]
public class BankController : ControllerBase

Handle errors

We have seen how to the validation errors works, but we still need to see how to handle exceptions in our application in order to return a problem details message. Thankfully, Kristian Hellang has already created a NuGet package for this purpose Hellang.Middleware.ProblemDetails.

Install-Package Hellang.Middleware.ProblemDetails -Version 3.0.0

Once we have installed it, we need to configure it. Open your Startup class and add the following code to the ConfigureServices method:

public void ConfigureServices(IServiceCollection services)
{
    services
        .AddProblemDetails(setup =>
        {
            setup.IncludeExceptionDetails = _ => Environment.IsDevelopment();
        })

    ...
}

We only include exception details in the problem details messages when we are running in Development mode. It’ll help us to diagnose our HTTP API while we develop.

And finally we need to add problem details to the ASP.NET Core pipeline in Configure method in our Startup class:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app
        .UseProblemDetails()
        .UseMvc();
}

If you want to test it, you can throw an exception in your action controller:

[HttpPost]
public ActionResult Transfer(TransferInfo model)
{
    throw new Exception("Testing problem details");

    return Ok();
}

Run your application and execute the action, you should see the following message:

Problem Details 4

As you can see (In Development mode) we have all the information available related to the exception but if we run our application in non-Development mode all this additional information dissapears:

Problem Details 5

We only need one more thing: What happens if I want to throw my own exceptions and map to custom problem details objects? No problem, You have a method called Map<> to map exceptions to custom problem details objects. Let me show you:

I’ve created a custom OutOfCreditException (This code must be in a service out of our controllers):

[HttpPost]
public ActionResult Transfer(TransferInfo model)
{
    throw new OutOfCreditException(
        "You do not have enough credit.",
        balance: 30,
        cost: 50);

    return Ok();
}

I’ve created also my custom problem details object:

internal class OutOfCreditProblemDetails : ProblemDetails
{
    public decimal Balance { get; set; }
}

The only thing we need left is to configure ProblemDetails how to map this exception with the problem details object. Open Startup.cs and change the method ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services
        .AddProblemDetails(setup =>
        {
            setup.IncludeExceptionDetails = _ => !Environment.IsDevelopment();
            setup.Map<OutOfCreditException>(exception => new OutOfCreditProblemDetails
            {
                Title = exception.Message,
                Detail = exception.Description,
                Balance = exception.Balance,
                Status = StatusCodes.Status403Forbidden,
                Type = exception.Type
            });
        })

    ...

}

Run you app and call the controller action and you should see the following message:

Problem Details 6

Conclusion

In this post I’ve tried to show you a way of specifying errors in HTTP API responses using Problem details and how to avoid to reinvent the wheel in every HTTP API, making easier to our clients handle these messages in a simple and standard way.

Links

Github Hellang.Middleware.ProblemDetails

Возможно, вам также будет интересно:

  • Asp net core 404 ошибка
  • Asmmap64 sys как исправить ошибку
  • Asl ошибка рендж ровер
  • Asko сушильная машина ошибка f10
  • Asko посудомоечная машина ошибка f11

  • Понравилась статья? Поделить с друзьями:
    0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии