Cara mendapatkan tindakan MVC untuk mengembalikan 404

142

Saya memiliki tindakan yang mengambil string yang digunakan untuk mengambil beberapa data. Jika string ini tidak menghasilkan data yang dikembalikan (mungkin karena telah dihapus), saya ingin mengembalikan 404 dan menampilkan halaman kesalahan.

Saat ini saya hanya menggunakan kembali tampilan khusus yang menampilkan pesan kesalahan ramah khusus untuk tindakan ini mengatakan bahwa item itu tidak ditemukan. Ini berfungsi dengan baik, tetapi idealnya ingin mengembalikan kode status 404 sehingga mesin pencari tahu bahwa konten ini tidak ada lagi dan dapat menghapusnya dari hasil pencarian.

Apa cara terbaik untuk masalah ini?

Apakah sesederhana mengatur Response.StatusCode = 404?

Paul Hiles
sumber
Anda juga harus menjaga Response.TrySkipIisCustomErrors = true; Jawaban oleh @ ganders adalah penyelamat ...
Thunder

Jawaban:

111

Ada beberapa cara untuk melakukannya,

  1. Anda benar dalam kode aspx umum yang dapat diberikan dengan cara yang Anda tentukan
  2. throw new HttpException(404, "Some description");
Dewfy
sumber
1
Satu hal yang harus diperhatikan adalah bahwa jika Anda memiliki halaman customError yang diatur untuk menangani 404 maka halaman kesalahan ini akan menghasilkan 200 (halaman yang tidak ditemukan ditemukan ... :-(). Saya cenderung membuang pengecualian dari katakanlah BlogController dan minta tindakan NotFound menetapkan kode respons yang tepat
Nigel Sampson
20
Saya akhirnya melakukan: Response.StatusCode = 404; Response.TrySkipIisCustomErrors = true; return View ("MyCustomView"); Ini berfungsi dengan baik dalam situasi saya.
Paul Hiles
@ PaulHiles: Ini adalah jawaban untuk saya di MVC3. Seandainya saya bisa memilihnya sebagai jawaban daripada komentar.
Valamas
Ini tidak berfungsi, saya pikir, jika menggunakan IIS. Di situs pengujian saya berfungsi dengan baik, tetapi di situs langsung halaman kesalahan kustom dimulai.
Andy Brown
@AndyBrown berfungsi untuk IIS dan juga untuk IIS Express, Anda perlu meninjau konfigurasi IIS Anda (Konsol admin)
Dewfy
150

Dalam ASP.NET MVC 3 dan di atas Anda dapat mengembalikan HttpNotFoundResult dari controller.

return new HttpNotFoundResult("optional description");
Stefan Paul Noack
sumber
4
penggunaan:return new HttpNotFoundResult("optional description");
Valamas
6
Jika Anda kembali dari dalam pengontrol ada juga metode kenyamanan yang disebut HttpNotFound(). Jadi Anda bisa kembali return HttpNotFound("optional description").
Luis Perez
1
Hal-hal yang tidak nyaman kembali pada tahun 2012 ;-)
Stefan Paul Noack
61

Di MVC 4 dan di atas Anda dapat menggunakan HttpNotFoundmetode pembantu bawaan:

if (notWhatIExpected)
{
    return HttpNotFound();
}

atau

if (notWhatIExpected)
{
    return HttpNotFound("I did not find message goes here");
}
Goding Coding
sumber
26

Kode:

if (id == null)
{
  throw new HttpException(404, "Your error message");//RedirectTo NoFoundPage
}

Web.config

<customErrors mode="On">
  <error statusCode="404" redirect="/Home/NotFound" />
</customErrors>
Sinan BARAN
sumber
Juga, semua kode status yang tersedia ada di enum ini: HttpStatusCode.
user2173353
12

Saya telah menggunakan ini:

Response.StatusCode = 404;
return null;
Wout
sumber
Terima kasih. Ini terlihat jauh lebih baik daripada melemparkan pengecualian yang mahal di server. Bertanya-tanya apakah 404 akan masuk log IIS ... idealnya akan.
fozylet
1
Tapi, di asp.net, metode ini bukan solusi yang bagus, bukan? karena halaman web akan menampilkan semua informasi sensitif terkait server.
lzlstyle
1
Satu pengecualian akan membutuhkan waktu kurang dari satu milidetik untuk menangani. Dibandingkan dengan beberapa ratus millseconds hanya untuk melakukan koneksi HTTP dan kembali itu tidak ada artinya. melempar HttpException atau mengembalikan HttpNotFoundResult, secara manual mengatur kode status dan mengembalikan null sangat buruk.
George
10

Jika Anda bekerja dengan .NET Core, Anda bisa return NotFound()

Robert Paulsen
sumber
5

Dalam NerdDinner misalnya. Coba itu

public ActionResult Details(int? id) {
    if (id == null) {
        return new FileNotFoundResult { Message = "No Dinner found due to invalid dinner id" };
    }
    ...
}
cem
sumber
Terima kasih, tetapi di balik layar, itu melempar HttpException mirip dengan saran nomor dua di pos Dewfy. Saya mencari sedikit lebih banyak kontrol sehingga saya dapat menampilkan halaman kesalahan yang bagus khusus untuk tindakan, tidak hanya mengarahkan ke halaman controller / global 404. Sepertinya mengatur kode status dan kembali ke tampilan khusus adalah cara yang sesuai untuk situasi saya.
Paul Hiles
4

Tidak ada contoh di atas yang berfungsi untuk saya hingga saya menambahkan garis tengah di bawah ini:

public ActionResult FourOhFour()
{
    Response.StatusCode = 404;
    Response.TrySkipIisCustomErrors = true; // this line made it work
    return View();
}
ganders
sumber
2
Apakah Anda serius memberi tahu saya bahwa yang sederhana return HttpNotFound();tidak berhasil untuk Anda? Berapa umur sistem Anda?
Hilang Coding
1
Apakah kamu sudah mencoba return HttpNotFound();? Ini berfungsi dengan baik dengan MVC 4 ke atas. msdn.microsoft.com/en-us/library/… "Properti TrySkipIisCustomErrors hanya digunakan ketika aplikasi Anda di-host di IIS 7.0. Ketika menjalankan dalam mode Klasik di IIS 7.0 nilai default properti TrySkipIisCustomErrors bernilai true. Ketika berjalan dalam mode Terpadu , nilai default properti TrySkipIisCustomErrors salah. "
Hilang Coding
2

Saya menggunakan:

Response.Status = "404 NotFound";

Ini bekerja untuk saya :-)

bruno
sumber
2

Di .NET Core 1.1:

return new NotFoundObjectResult(null);
feedthedogs
sumber
1
Jika Anda tidak mengembalikan objek kemudian mengembalikan NotFound () lebih tepat tetapi dalam kedua kasus tersebut, Anda tidak akan mendapatkan halaman kesalahan yang ramah kecuali Anda menanganinya dengan sesuatu seperti StatusCodePagesWithReExecute. Lihat devtrends.co.uk/blog/handling-404-not-found-in-asp.net-core
Paul Hiles
0

Anda juga dapat melakukan:

        if (response.Data.IsPresent == false)
        {
            return StatusCode(HttpStatusCode.NoContent);
        }
Christof Mehlstäubler
sumber
-1

Silakan coba kode demo berikut:

public ActionResult Test()

{
  return new HttpStatusCodeResult (404,"Not found");
}
pengguna4326800
sumber