Nasıl düzgün ASP.NET MVC 404 işleyebilir miyim?
Sadece benimle ASP.NET MVC çok ayı yeni başlıyorum. Site ve çeşitli diğerleri bu civarında aradım ve bu birkaç uygulamaları gördük.
EDİT: RC2 kullanıyorum söylemeyi unutmuşum
URL Yönlendirme kullanma
routes.MapRoute(
"Error",
"{*url}",
new { controller = "Errors", action = "NotFound" } // 404s
);
Yukarıdaki bu gibi istekleri (varsayarak varsayılan rota tabloları ilk MVC projesi tarafından Kur) dikkat çekmek gibi görünüyor: "" . /bla/bla/bla/bla
() Geçersiz kılma HandleUnknownAction denetleyicisi kendisi
// 404s - handle here (bad action requested
protected override void HandleUnknownAction(string actionName) {
ViewData["actionName"] = actionName;
View("NotFound").ExecuteResult(this.ControllerContext);
}
Ancak önceki stratejileri Kötü/Bilinmeyen bir denetleyici için bir istek işleyemez. Örneğin, bir "yönlendirme geçersiz kullanırsam", eğer bu isteği web sunucusu genel 404 sayfa ve benim 404 Not alıyorum. İDoNotExist/yok
Sonunda, benim sorum:Bu tür istek, bir rota veya MVC çerçevesinde başka bir şey kullanmadan yakalamak için herhangi bir şekilde kendisini var mı?
YA da sadece Web kullanarak varsayılan gerekir.Benim 404 işleyicisi olarak Config customErrors ve tüm bu unutmak? Eğer /Web Görüşleri nedeniyle dışında genel 404 sayfa depolamak lazım customErrors ile gidersem sanırım.Doğrudan erişim kısıtlamaları Config. Zaten en iyi uygulamalar veya herhangi bir rehberlik takdir edilir.
CEVAP
404 gereksinimleri
Aşağıdaki 404 çözümü için, ihtiyaçlarına ve ben aşağıda nasıl yapılacağını göster ben bunu uygulamak:
- Kötü eylemleri ile eşleşti yolları işlemek istiyorum
- Kötü denetleyicileri ile eşleşti yolları işlemek istiyorum
- Uyumlu un yolları (uygulamam anlayamayan keyfi URL) kontrol etmek istiyorum - bu dünya kadar köpüren istemiyorum.çünkü o zaman asax veya IIS 26**
- Bir yol üstünde, özel olarak aynı şekilde bir KİMLİK var olmayan bir nesne için gönderildiğinde gibi 404'ler - (belki silinmiş) ele almak istiyorum
- Benim 404 hataları için gerekirse daha fazla veri daha sonra pompa edebilirim MVC görünümü (statik sayfa) (good 404 designs) geri dönmek istiyorumveonlargerekirHTTP 404 durum kodunu döndürür
Çözüm
Genel Application_Error
kaydetmek gerektiğini düşünüyorum.işlenmeyen özel durumlar ve günlüğü (Shay Jacoby's answer gösterir gibi) gibi yüksek bir şey için asax ama 404 işleme. Bu benim önerim Global dışarı 404 tutuyor neden olur.dosya asax.
Adım 1: 404-hata mantık . için ortak bir yer Var
Bu sürdürülebilirlik için iyi bir fikirdir. Senin için gelecek geliştirmeleri well designed 404 page kolayca uyum sağlamaları ErrorController kullanın. Ayrıca,yanıtınız 404 kodu olduğundan emin olun!
public class ErrorController : MyController
{
#region Http404
public ActionResult Http404(string url)
{
Response.StatusCode = (int)HttpStatusCode.NotFound;
var model = new NotFoundViewModel();
// If the url is relative ('NotFound' route) then replace with Requested path
model.RequestedUrl = Request.Url.OriginalString.Contains(url) & Request.Url.OriginalString != url ?
Request.Url.OriginalString : url;
// Dont get the user stuck in a 'retry loop' by
// allowing the Referrer to be the same as the Request
model.ReferrerUrl = Request.UrlReferrer != null &&
Request.UrlReferrer.OriginalString != model.RequestedUrl ?
Request.UrlReferrer.OriginalString : null;
// TODO: insert ILogger here
return View("NotFound", model);
}
public class NotFoundViewModel
{
public string RequestedUrl { get; set; }
public string ReferrerUrl { get; set; }
}
#endregion
}
Adım 2: kolayca özel 404 eylem çağırmak ve HandleUnknownAction
Tel böylece temel Denetleyici bir sınıfı Kullanın
ASP.NET MVC 404'ler yerlerde bir dizi de yakalanmış olması gerekir. İlk HandleUnknownAction
.
InvokeHttp404
yöntemi ErrorController
Http404
yeni eylem için yeniden yönlendirme için ortak bir yer oluşturur. DRY düşün!
public abstract class MyController : Controller
{
#region Http404 handling
protected override void HandleUnknownAction(string actionName)
{
// If controller is ErrorController dont 'nest' exceptions
if (this.GetType() != typeof(ErrorController))
this.InvokeHttp404(HttpContext);
}
public ActionResult InvokeHttp404(HttpContextBase httpContext)
{
IController errorController = ObjectFactory.GetInstance<ErrorController>();
var errorRoute = new RouteData();
errorRoute.Values.Add("controller", "Error");
errorRoute.Values.Add("action", "Http404");
errorRoute.Values.Add("url", httpContext.Request.Url.OriginalString);
errorController.Execute(new RequestContext(
httpContext, errorRoute));
return new EmptyResult();
}
#endregion
}
Adım 3: Denetleyicisi Fabrika Bağımlılık Enjeksiyon Kullanın ve 404 HttpExceptions Tel
Yani (StructureMap olmak zorunda değil) gibi
MVC1.0 örnek:
public class StructureMapControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(Type controllerType)
{
try
{
if (controllerType == null)
return base.GetControllerInstance(controllerType);
}
catch (HttpException ex)
{
if (ex.GetHttpCode() == (int)HttpStatusCode.NotFound)
{
IController errorController = ObjectFactory.GetInstance<ErrorController>();
((ErrorController)errorController).InvokeHttp404(RequestContext.HttpContext);
return errorController;
}
else
throw ex;
}
return ObjectFactory.GetInstance(controllerType) as Controller;
}
}
MVC2.0 örnek:
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
try
{
if (controllerType == null)
return base.GetControllerInstance(requestContext, controllerType);
}
catch (HttpException ex)
{
if (ex.GetHttpCode() == 404)
{
IController errorController = ObjectFactory.GetInstance<ErrorController>();
((ErrorController)errorController).InvokeHttp404(requestContext.HttpContext);
return errorController;
}
else
throw ex;
}
return ObjectFactory.GetInstance(controllerType) as Controller;
}
Daha kendi hataları onlar geldiği yerin yakınına yakalamak için sanırım. Bu Application_Error
işleyicisi için yukarıdaki yüzden tercih ediyorum.
Bu 404 hataları yakalamak için ikinci ev.
Adım 4: Küresel NotFound için bir yol Ekleyin.uygulamanız ayrıştırılması başarısız olan adresi için asax
Bu yol Http404
bizim eylem için işaret etmelidir. url
param yönlendirme motoru burada etki alanı bölümü sıyırma olduğu için göreli bir url olacak fark ettin mi? 1. Adımda tüm o koşullu url mantığı var.
routes.MapRoute("NotFound", "{*url}",
new { controller = "Error", action = "Http404" });
Bu kendini çağırmak olmadığını MVC uygulaması 404 hataları yakalamak için üçüncü ve son yerdir. Eğer burada MVC sorunu kaçırmak için ASP.NET (Global.eşsiz yollar, Ne olursa.asax) ve gerçekten bu durumda sen bunu istemiyorsun.
Adım 5: son olarak, app bir şey bulamadıkları zaman 404 hataları çağırır
Kötü bir KİMLİĞİ benim Kredi denetleyicisi gönderildiğinde (MyController
türetir) gibi
//
// GET: /Detail/ID
public ActionResult Detail(int ID)
{
Loan loan = this._svc.GetLoans().WithID(ID);
if (loan == null)
return this.InvokeHttp404(HttpContext);
else
return View(loan);
}
Tüm bu daha az kod ile daha az yerlerde bağladım olabilir ama bu çözüm, daha sürdürülebilir, daha fazla test edilebilir ve oldukça pragmatik olduğunu düşünüyorum eğer iyi olurdu.
Yorumunuz için teşekkürler şimdiye kadar. Daha fazla almak isterdim.
NOT: Bu önemli ölçüde orijinal cevabım ama yerine aynı - bu yeni bir cevap ekledim neden amacı düzenlenmiştir
Nasıl bir Excel PHP UTF-8 CSV düzgün o...
Nasıl Jade ile satır içi JavaScript iş...
Nasıl kontrol "global değişken&qu...
Nasıl düzgün bir Seçme sorgusu için bi...
Nasıl UseEmbeddedHttpServer doğru 2 ka...