Özel ASP.NET MVC 404 Hata sayfası için yönlendirme


116

Birisi, genel "Kaynak Bulunamadı" ASP.NET hatasını görüntülemek yerine, ASP.NET MVC'de geçerli bir eylemi veya denetleyiciyi çağırmayan bir URL yazdığında özel bir HTTP 404 hata sayfası oluşturmaya çalışıyorum.

Bunu halletmek için web.config'i kullanmak istemiyorum.

Geçersiz URL'leri yakalamak için yapabileceğim herhangi bir yönlendirme sihri var mı?

Güncelleme: Verilen yanıtı denedim, ancak yine de çirkin "Kaynak Bulunamadı" mesajını alıyorum.

Başka bir güncelleme: Tamam, görünüşe göre RC1'de bir şeyler değişti. Hatta özellikle 404'ü bir üzerinde yakalamayı denedim HttpExceptionve bu hala bana "Kaynak Bulunamadı" sayfasını veriyor.

MvcContrib'in kaynağının özelliğini bile kullandım ve hiçbir şey - aynı sorun. Herhangi bir fikir?



@Peter Bu, bir eylem olmadığında bir sayfa bulunamadı görünümü göstermek için HandleUnknownAction'ı geçersiz kılmakla birlikte ekledim ve ardından kullanıcıların yazabileceği başka riskli herhangi bir şeyi işlemek için ASP.net'te yerleşik özel hata işleyicisi .
dswatik


8
Diğer kullanıcıların küstahça davranmasından ve "Bunu neden yapmak isteyesiniz? Sadece şunu yapın ..." gibi şeyler söylemesinden nefret ediyorum. Ancak, web.config yaklaşımını kullanmanızı engelleyen hiçbir şey yoksa ve ihtiyaçlarınızı karşılar, standart ve şık bir yaklaşımdır. Bu yaklaşımla ilgili herhangi bir geri bildirim takdir edilmektedir, çünkü onunla ilgili bilmediğim bazı sorunlar olabilir.
Sean

Yanıtlar:


10

Rotalar tablosunun sonuna tüm rotayı yakala öğesini ekleyin ve onunla istediğiniz sayfayı görüntüleyin.

Bkz: ASP.NET MVC için '404 sayfa bulunamadı' sorgularını işlemek için tüm yolu nasıl yakalayabilirim?


Ancak bunu denedim, yine de çirkin ASP.NET varsayılan Kaynak Bulunamadı Mesajı
alıyorum

3
Bu soruna kesin (ve esnek !!) bir çözüm bulamıyorum ne bu cevapta ne de sağlanan bağlantıda.
Peter

4
Ben de bilmiyorum ... bu biraz karmaşık bir cevap gibi görünüyor. CustomErrors'ın WebForms'da yaptıkları gibi davranmasını sağlamanın bir yolunu arıyorum. Herhangi bir fikir?
JC Grubbs

1
Bu hem işe yaramıyor hem de prensipte kötü. Daha önceki yönlendirme modellerinden biriyle eşleşen kötü URL'leri yakalayamayacağı için işe yaramaz. Prensip olarak kötü çünkü hata olması gereken şeyi hata değil haline dönüştürür . "Hata" olarak adlandırdığınız bir sayfaya yeniden yönlendirmek, bir hata sayfasına yeniden yönlendirmekten farklıdır. Bunu bir hata olarak tutmak, hatayı günlüğe kaydetmek ve ardından bir hata olarak ele almak istiyorsunuz. Hatalar değerli bilgilerdir.
Matthew

105

3 saat boyunca üretim sunucusunda özel hataları etkinleştirmeye çalıştım, bunu ASP.NET MVC'de herhangi bir rota olmadan nasıl yapacağıma dair nihai çözümü buldum.

ASP.NET MVC uygulamasında özel hataları etkinleştirmek için ihtiyacımız olan (IIS 7+):

  1. Web yapılandırmasında özel sayfaları şu system.webbölümde yapılandırın :

    <customErrors mode="RemoteOnly"  defaultRedirect="~/error">
        <error statusCode="404" redirect="~/error/Error404" />
        <error statusCode="500" redirect="~/error" />
    </customErrors>

    RemoteOnlyyerel ağda gerçek hatalar göreceğiniz anlamına gelir (geliştirme sırasında çok yararlıdır). Ayrıca herhangi bir hata kodu için hata sayfasını yeniden yazabiliriz.

  2. Sihirli Yanıt parametresini ve yanıt durum kodunu ayarlayın (hata işleme modülünde veya hata tutamaç özelliğinde)

      HttpContext.Current.Response.StatusCode = 500;
      HttpContext.Current.Response.TrySkipIisCustomErrors = true;
  3. system.webServerBölümün altındaki web yapılandırmasında başka bir sihirli ayar ayarlayın :

    <httpErrors errorMode="Detailed" />

Bu bulduğum son şeydi ve bundan sonra üretim sunucusunda özel hataları görebiliyorum.


8
Bu hala ideal bir çözüm değil. Size uygun HTTP yanıt kodlarını vermez. customErrorsSonuçları, yalnızca hata sayfanızı yüklemek için 302 yönlendirmesinde kullanmak .
Justin Helgerson

@ Ek0nomik İdeal çözümleri hiç görmedim :)
Andrew Orsich

2
@JustinHelgerson Her durum kodu için bir ErrorController kuruyorum ve bu eylemlerin içindeki Yanıt Kodlarını ayarlıyorum ve yanıt kodlarını ince ayarlıyorum. Fiddler ile test ettim ve 404 durum kodları bir 404 ile yanıt veriyor ve 500 hata içeren sayfalar bir 500 ile yanıt veriyor. Ve her iki durumda da özel hata görünümlerim sunuluyor
Shane Neuville

Ekip arkadaşım burada ve burada belirtildiği gibi Özel Hata Sayfasına yönlendirmek için 500 durum koduyla çalışma zamanı hatası yapmak için Paylaşılan klasör altındaki Hata görünümünü sildi . Umut birine yardım eder.
shaijut

41

Bu makaledeki görünümleri döndüren bir ErrorController oluşturarak hata işlememi çalıştırdım. Global.asax'taki rotaya "Tümünü Yakala" seçeneğini de eklemem gerekiyordu.

Web.config dosyasında yoksa bu hata sayfalarından herhangi birine nasıl ulaşacağını göremiyorum ..? Web.config dosyamın şunu belirtmesi gerekiyordu:

customErrors mode="On" defaultRedirect="~/Error/Unknown"

ve sonra şunu da ekledim:

error statusCode="404" redirect="~/Error/NotFound"

2
Teşekkürler - bu 2 yıl sonra bana yardımcı oldu! Yalnızca 404 için özel bir hata istiyorsanız, başka bir şey istemiyorsanız ne yaparsınız?
Shaul Behr

1
@Shaul bir yıl sonra ... defaultRedirect'i ayarlamayın, özniteliği tamamen hariç tutun.
një

27

Kaynak

NotFoundMVC - ASP.NET MVC3 uygulamanızda bir denetleyici, eylem veya yol bulunamadığında kullanıcı dostu bir 404 sayfası sağlar. Varsayılan ASP.NET hata sayfası yerine NotFound adlı bir görünüm oluşturulur.

Bu eklentiyi kullanarak nuget aracılığıyla ekleyebilirsiniz: Install-Package NotFoundMvc

NotFoundMvc, web uygulaması başlatılırken kendisini otomatik olarak yükler. Bir 404 HttpException genellikle ASP.NET MVC tarafından atılan tüm farklı yolları işler. Bu, eksik bir denetleyici, eylem ve rotayı içerir.

Adım Adım Kurulum Kılavuzu:

1 - Projenize sağ tıklayın ve Nuget Paketlerini Yönet'i seçin ...

2 - Arayın NotFoundMvcve kurun. görüntü açıklamasını buraya girin

3 - Kurulum tamamlandıktan sonra projenize iki dosya eklenecektir. Aşağıdaki ekran görüntülerinde gösterildiği gibi.

görüntü açıklamasını buraya girin

4 - Views / Shared'da bulunan yeni eklenen NotFound.cshtml dosyasını açın ve isteğinize göre değiştirin. Şimdi uygulamayı çalıştırın ve yanlış bir url yazın, Kullanıcı dostu bir 404 sayfasıyla karşılaşacaksınız.

görüntü açıklamasını buraya girin

Artık kullanıcılar gibi hata mesajları alacak mı? Server Error in '/' Application. The resource cannot be found.

Bu yardımcı olur umarım :)

Not: Andrew Davey'e harika bir eklenti yaptığı için tebrikler.


@niico Kaynak koduna bakıldığında yanıt kodunu 404 olarak ayarlıyor gibi görünüyor, yani evet.
Will Dean

20

IIS hata sayfalarını değiştirmek için bunu web.config dosyasında deneyin. Bu tahmin ettiğim en iyi çözüm ve doğru durum kodunu da gönderiyor.

<system.webServer>
  <httpErrors errorMode="Custom" existingResponse="Replace">
    <remove statusCode="404" subStatusCode="-1" />
    <remove statusCode="500" subStatusCode="-1" />
    <error statusCode="404" path="Error404.html" responseMode="File" />
    <error statusCode="500" path="Error.html" responseMode="File" />
  </httpErrors>
</system.webServer>

Tipila'dan daha fazla bilgi - Özel Hata Sayfalarını Kullanın ASP.NET MVC


1
+1. Bu, MVC5'te birden çok alanda benim için tutarlı bir şekilde çalışıyor gibi görünen tek şeydi.
hawkke

Bu en kolay çözümdür. Yine de hata sayfanızda ustura sözdizimini kullanamazsınız.
highace

15

Bu çözüm, web.config dosyası değişikliklerine veya tümünü yakalama yollarına ihtiyaç duymaz.

İlk önce bunun gibi bir kontrolör oluşturun;

public class ErrorController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Title = "Regular Error";
        return View();
    }

    public ActionResult NotFound404()
    {
        ViewBag.Title = "Error 404 - File not Found";
        return View("Index");
    }
}

Ardından görünümü "Views / Error / Index.cshtml" altında şu şekilde oluşturun;

 @{
      Layout = "~/Views/Shared/_Layout.cshtml";
  }                     
  <p>We're sorry, page you're looking for is, sadly, not here.</p>

Ardından Global asax dosyasına aşağıdaki gibi ekleyin:

protected void Application_Error(object sender, EventArgs e)
{
        // Do whatever you want to do with the error

        //Show the custom error page...
        Server.ClearError(); 
        var routeData = new RouteData();
        routeData.Values["controller"] = "Error";

        if ((Context.Server.GetLastError() is HttpException) && ((Context.Server.GetLastError() as HttpException).GetHttpCode() != 404))
        {
            routeData.Values["action"] = "Index";
        }
        else
        {
            // Handle 404 error and response code
            Response.StatusCode = 404;
            routeData.Values["action"] = "NotFound404";
        } 
        Response.TrySkipIisCustomErrors = true; // If you are using IIS7, have this line
        IController errorsController = new ErrorController();
        HttpContextWrapper wrapper = new HttpContextWrapper(Context);
        var rc = new System.Web.Routing.RequestContext(wrapper, routeData);
        errorsController.Execute(rc);

        Response.End();
}

Bunu yaptıktan sonra hala özel IIS hata sayfasını alıyorsanız, web yapılandırma dosyasında aşağıdaki bölümlerin yorumlandığından (veya boş olduğundan) emin olun:

<system.web>
   <customErrors mode="Off" />
</system.web>
<system.webServer>   
   <httpErrors>     
   </httpErrors>
</system.webServer>

Bir 404 genellikle web sunucusu tarafından yakalandığından ve bu nedenle hiçbir zaman uygulama düzeyinde ele alınmadığından, bu yaklaşımın her durumda işe yarayacağını düşünmüyorum.
Chris Halcrow

Bu yaklaşımı kullanırsanız, Response.End();Application_Error işleyicinizin sonuna bir eklemenizi tavsiye ederim . Bu olmadan, belirli bir oturum için bir hatanın yalnızca ilk oluşumu tetiklenir; bu, örneğin, Application_Error işleyicisinde özel hata günlüğü tuttuğunuzda bir sorundur.
Keith

6

Eğer MVC 4'te çalışıyorsanız, izleyebilir bu çözümü , benim için çalıştı.

Aşağıdaki Application_Error yöntemini ekle Global.asax:

protected void Application_Error(object sender, EventArgs e)
{
    Exception exception = Server.GetLastError();
    Server.ClearError();

    RouteData routeData = new RouteData();
    routeData.Values.Add("controller", "Error");
    routeData.Values.Add("action", "Index");
    routeData.Values.Add("exception", exception);

    if (exception.GetType() == typeof(HttpException))
    {
        routeData.Values.Add("statusCode", ((HttpException)exception).GetHttpCode());
    }
    else
    {
        routeData.Values.Add("statusCode", 500);
    }

    IController controller = new ErrorController();
    controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
    Response.End();

Denetleyicinin kendisi gerçekten basit:

public class ErrorController : Controller
{
    public ActionResult Index(int statusCode, Exception exception)
    {
        Response.StatusCode = statusCode;
        return View();
    }
}

GitHub'da Mvc4CustomErrorPage'in tam kaynak kodunu kontrol edin .


0

Aynı problemi yaşadım, yapmanız gereken şey, Görünümler klasörünüzdeki web.config dosyasına customErrors özniteliğini eklemek yerine, bunu projelerinizin kök klasöründeki web.config dosyasına eklemeniz gerektiğidir.


0

İşte hata sayfasının tek bir yerde tamamen özelleştirilmesine izin veren gerçek cevap. Web.config'i değiştirmeye veya ayrı bir kod oluşturmaya gerek yok.

MVC 5'te de çalışır.

Bu kodu denetleyiciye ekleyin:

        if (bad) {
            Response.Clear();
            Response.TrySkipIisCustomErrors = true;
            Response.Write(product + I(" Toodet pole"));
            Response.StatusCode = (int)HttpStatusCode.NotFound;
            //Response.ContentType = "text/html; charset=utf-8";
            Response.End();
            return null;
        }

Göre http://www.eidias.com/blog/2014/7/2/mvc-custom-error-pages


0

Bazı özel durumlar hakkında konuşacağım,

HomeController'da 'PageNotFound yöntemi' kullanıyorsanız, aşağıdaki gibi

[Route("~/404")]
public ActionResult PageNotFound()
{
  return MyView();
}

bu işe yaramaz. Ancak Rota etiketlerini aşağıdaki gibi temizlemelisiniz,

//[Route("~/404")]
public ActionResult PageNotFound()
{
  return MyView();
}

Bunu web.config dosyasında yöntem Adı olarak değiştirirseniz çalışır. Ancak web.config dosyasında aşağıdaki gibi kod yazmayı unutmayın

<customErrors mode="On">
  <error statusCode="404" redirect="~/PageNotFound" /> 
 *// it is not "~/404" because it is not accepted url in Route Tag like [Route("404")]*
</customErrors>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.