Avatar billede jps6kb Novice
27. november 2007 - 16:38 Der er 19 kommentarer og
1 løsning

Håndtering af "File or directory not found"

Hey,

Hvordan håndterer jeg alle 404 i ASP.NET?

Hvis jeg sætter det op i web.config så virker det kun på .aspx sider jo.

Det skal være sådan, at www.mitsite.com/sdgadths bliver grebet også.
Avatar billede erikjacobsen Ekspert
27. november 2007 - 16:56 #1
På din egen server kan du mange ting i IIS-kontrolpanel.
På et webhotel kan du vel kun hvad der er tilgængeligt i kontrolpanelet, hvor man sommetider kan sætte en 404-redirect op.
Avatar billede jps6kb Novice
27. november 2007 - 17:04 #2
Okay.. jeg synes jeg har læst at man kan bruge et modul ellers.. men jeg har ikke kunnet finde nogen. Det er fordi udbyderen vil have en masse penge for at sætte det op, da det ikke er i kontrolpanelet.
Lidt noget bondefangeri.
Avatar billede erikjacobsen Ekspert
27. november 2007 - 17:13 #3
Ja, der er et modul (eller flere). Men kan til en vis grad klare det med en 404-redirect - og det kan du heller ikke kontrolpanelet?
Avatar billede jps6kb Novice
27. november 2007 - 17:43 #4
Nej, det er wannafind.. jeg må sige at jeg er rigtig skuffet over dem, men det er ikke mit webhotel.. heldigvis.

Har du link til nogle moduler?
Avatar billede erikjacobsen Ekspert
27. november 2007 - 21:25 #5
Nej, jeg følger ikke med i det. Og jeg kender heller ikke wannafind.
Avatar billede nielle Nybegynder
27. november 2007 - 22:31 #6
Det kunne eventuelt laves vha. et HttpModule:

Tilføj dette til din web.config:

    <system.web>
      <httpModules>
        <add type="NotFoundHttpModule.NotFoundHttpModuleClass, NotFoundHttpModule" name="NotFoundHttpModule"/>
      </httpModules>
    </system.web>

Derefter opretter du et DLL-projekt med mavnet "NotFoundHttpModule" og med følgende indhold:

using System;
using System.IO;
using System.Web;

namespace NotFoundHttpModule
{
    public class NotFoundHttpModuleClass : IHttpModule
    {
        #region IHttpModule Members

        public void Dispose() { }

        public void Init(HttpApplication context)
        {
            context.BeginRequest += new System.EventHandler(context_BeginRequest);
        }

        #endregion

        void context_BeginRequest(object sender, EventArgs e)
        {
            HttpApplication app = sender as HttpApplication;

            string path = app.Context.Request.PhysicalPath;

            if (Directory.Exists(path) && File.Exists(path))
            {
                // Alt ok ... vi lader den passere.
            }
            else
            {
                Error(app);
            }
        }

        private void Error(HttpApplication app)
        {
            app.Context.Response.Redirect(app.Server.MapPath("404.aspx"));

            // Alternativt:
            // context.Context.Response.StatusCode = 404;
            // context.Context.Response.SuppressContent = true;
            // context.Context.Response.End();
        }
    }
}

Dette kompiler du og hvorefter du uploader den resulterende DLL til bin-folderen på websitet.
Avatar billede erikjacobsen Ekspert
27. november 2007 - 22:55 #7
Men, nielle, er det ikke kun hvis det der requestes en .aspx-fil (eller noget andet ASP.NET), der ikke er der ?
Avatar billede nielle Nybegynder
27. november 2007 - 23:07 #8
Den håndtere ethvert request til webserveren. Den bliver kaldt før noget som helst andet.
Avatar billede arne_v Ekspert
28. november 2007 - 01:52 #9
Så er min IIS/ASP.NET defekt - den kalde kun modul for .aspx, .asmx etc. men ikke
for .html, .foobar etc.
Avatar billede nielle Nybegynder
28. november 2007 - 07:34 #10
Jeg har nu godt nok kun testet den via den indbyggede Development Server, men der virker det altså. Jeg skal ikke sværge på at dette så kan overføres til IIS'en.

Den kaldes for samtlige adresser jeg taster ind i browserens adresselinje. Om det er en sti der ville føre til et directory, eller om det er en fil ... .aspx, .html og også .foobar.
Avatar billede nielle Nybegynder
28. november 2007 - 07:35 #11
Der er i øvrigt en lille fejl i koden:

if (Directory.Exists(path) && File.Exists(path))

skal selvfølgelig være:

if (Directory.Exists(path) || File.Exists(path))
Avatar billede jps6kb Novice
28. november 2007 - 11:37 #12
Jeg har en idé om, at jeg gør det forkert, for den vil ikke kendes ved "HttpApplication" og "IHttpModule"? :)
Avatar billede nielle Nybegynder
28. november 2007 - 11:52 #13
Du skal nok oprette en reference til System.Web.dll filen fra dit DLL projekt. Det gør du ude i højre side af din VS ved at vælge Add Reference og så browse dig frem til den under .Net fanen.
Avatar billede jps6kb Novice
28. november 2007 - 17:56 #14
Det virker ikke lokalt i hvertfald. Den er pænt ligeglad.
Den kører dll'en, for jeg havde glemt at rette && til || .. og så kunne den, logisk nok, ikke åbne Default.aspx .. men alt andet.. også .aspx filer redirecter den ikke til 404.aspx.
Avatar billede nielle Nybegynder
28. november 2007 - 18:26 #15
Der var også en lille fejl mere - ikke noget med at bruge MapPath() når man skal redirekte:

        private void Error(HttpApplication app)
        {
            string errFile = "404.aspx";
            app.Context.Response.Redirect(errFile);

            // Alternativt
            // context.Context.Response.StatusCode = 404;
            // context.Context.Response.SuppressContent = true;
            // context.Context.Response.End();
        }
Avatar billede jps6kb Novice
28. november 2007 - 18:45 #16
Så virker det lokalt, men ikke på webhotellet desværre.
Avatar billede nielle Nybegynder
28. november 2007 - 21:19 #17
Så der der åbenbart i det mindste en forskel på den indbyggede Development Server i VS og så en rigtig IIS.

Jeg har kigget i den dokumentation som jeg har kunnet finde, og dette er hvad jeg har lært i den sammenhæng:

En IIS kan konfigureres til at sende alle requests videre til ASP.Net. Det er bl.a. sådan at man kan komme til at lave URL'rewriting via ASP.Net. Det er faktisk en ganske lille konfigurations-ændring når det kommer til stykket: ".*" filer skal blot mappes til aspnet_isapi.dll applikationen.

<ironi> Forståligt nok er det noget dit webhotel skal have mange penge for... </ironi>

Der er dog sikkert nogle sikkerhedsmæssige aspekter, som gør at man ikke ville ænske at sætte sit site sådan op uden at tænke sig godt om, men den del tør jeg slet ikke udtale mig om.

Requests udefra rammer først IIS'en. Derefter bliver de sendt igennem systemet på nogenlunde nedenstående facon (skal nok pastes til notepad for at give mening):

-> IIS -> HTTP-runtime -> HTTP-module -> HTTP-module -> HTTP-module -> HTTP-handler -> Fil ... <--requests
  IIS    HTTP-runtime    HTTP-module    HTTP-module    HTTP-module    HTTP-handler    Fil
<- IIS <- HTTP-runtime <- HTTP-module <- HTTP-module <- HTTP-module <- HTTP-handler <- Fil ... <--response

Dvs. at der kan være nul eller flere HTTP-moduler involveret men kun en HTTP-handler. Rent faktisk behøver der ikke nødvendigvis at være en fil; Respons kan godt genereres direkte af modulerne eller handleren.

HTTP-modulerne kommer altså efter IIS'en i eksekverings rækkefølgen og uden den ovennævnte konfiguration bliver requests slet ikke sendt videre fra IIS'en til HTTP-runtime'en. Og så har alle de moduler man måtte vælge at tilføje ingen som helst effekt.

Dermed er vi (næsten) tilbage til Eriks' svar i 27/11-2007 16:56:39. :^|

Så desværre...
Avatar billede jps6kb Novice
02. december 2007 - 09:52 #18
Fair nok. :) Smider i lige svar?
Avatar billede nielle Nybegynder
02. december 2007 - 09:55 #19
Svar :^)
Avatar billede erikjacobsen Ekspert
02. december 2007 - 11:10 #20
Ingen point til mig, tak.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester