যদি রুটটি দেওয়া হয়:
{ফিডনাম} / tem আইটেমপার্মালিংক}
প্রাক্তন: / ব্লগ / হ্যালো-ওয়ার্ল্ড
যদি আইটেমটি বিদ্যমান না থাকে তবে আমি একটি 404 ফিরিয়ে দিতে চাই A এএসপি.নেট এমভিসিতে এটি করার সঠিক উপায় কী?
যদি রুটটি দেওয়া হয়:
{ফিডনাম} / tem আইটেমপার্মালিংক}
প্রাক্তন: / ব্লগ / হ্যালো-ওয়ার্ল্ড
যদি আইটেমটি বিদ্যমান না থাকে তবে আমি একটি 404 ফিরিয়ে দিতে চাই A এএসপি.নেট এমভিসিতে এটি করার সঠিক উপায় কী?
উত্তর:
হিপ থেকে শুটিং (কাউবয় কোডিং ;-)), আমি এই জাতীয় কিছু প্রস্তাব করব:
নিয়ামক:
public class HomeController : Controller
{
public ActionResult Index()
{
return new HttpNotFoundResult("This doesn't exist");
}
}
এইচটিপিএনটফাউন্ডআরসাল্ট:
using System;
using System.Net;
using System.Web;
using System.Web.Mvc;
namespace YourNamespaceHere
{
/// <summary>An implementation of <see cref="ActionResult" /> that throws an <see cref="HttpException" />.</summary>
public class HttpNotFoundResult : ActionResult
{
/// <summary>Initializes a new instance of <see cref="HttpNotFoundResult" /> with the specified <paramref name="message"/>.</summary>
/// <param name="message"></param>
public HttpNotFoundResult(String message)
{
this.Message = message;
}
/// <summary>Initializes a new instance of <see cref="HttpNotFoundResult" /> with an empty message.</summary>
public HttpNotFoundResult()
: this(String.Empty) { }
/// <summary>Gets or sets the message that will be passed to the thrown <see cref="HttpException" />.</summary>
public String Message { get; set; }
/// <summary>Overrides the base <see cref="ActionResult.ExecuteResult" /> functionality to throw an <see cref="HttpException" />.</summary>
public override void ExecuteResult(ControllerContext context)
{
throw new HttpException((Int32)HttpStatusCode.NotFound, this.Message);
}
}
}
// By Erik van Brakel, with edits from Daniel Schaffer :)
এই পদ্ধতির ব্যবহার করে আপনি কাঠামোর মান মেনে চলেন। সেখানে ইতিমধ্যে একটি এইচটিটিপিউনাওরাইজড রিসাল্ট রয়েছে, সুতরাং এটি পরে আপনার কোড বজায় রেখে অন্য বিকাশকারীর চোখে কাঠামোটি প্রসারিত করবে (আপনি জানেন, আপনি কোথায় থাকেন সাইকো জানেন)।
আপনি কীভাবে এইচটিটিপিউনাথরাইজড রিসাল্ট অর্জন করা হয় তা দেখতে সমাবেশের দিকে নজর দেওয়ার জন্য আপনি প্রতিবিম্বকে ব্যবহার করতে পারেন, কারণ আমি জানি না যে এই পদ্ধতির কোনও কিছুই মিস হয় না (এটি প্রায় খুব সহজ বলে মনে হয়)।
আমি এই মুহুর্তে এইচটিটিপিউনাথরাইজড রেজাল্টটি একবার দেখার জন্য রিফ্লেক্টর ব্যবহার করেছি। তারা 0x191 (401) এর প্রতিক্রিয়ায় স্থিতি কোডটি সেট করছে বলে মনে হচ্ছে। যদিও এটি 401 এর জন্য কাজ করে, 404 কে নতুন মান হিসাবে ব্যবহার করে আমি মনে করি ফায়ারফক্সে কেবল একটি ফাঁকা পৃষ্ঠা পাচ্ছি। ইন্টারনেট এক্সপ্লোরার একটি ডিফল্ট 404 দেখায় যদিও (ASP.NET সংস্করণ নয়)। ওয়েব-ডেভেলপার সরঞ্জামদণ্ডটি ব্যবহার করে আমি এফএফ-এ শিরোনামগুলি পরিদর্শন করেছি, যা একটি 404 পাওয়া যায়নি প্রতিক্রিয়া দেখায়। কেবল এফএফ-তে আমি ভুল কনফিগার করা এমন কিছু হতে পারে।
এটি বলা হচ্ছে, আমি মনে করি জেফের দৃষ্টিভঙ্গি KISS এর একটি সূক্ষ্ম উদাহরণ। আপনার যদি এই নমুনায় সত্যই ভারবোসিটির প্রয়োজন না হয় তবে তার পদ্ধতিটিও ঠিকঠাকভাবে কাজ করে।
আমরা এটি যেমন করি; এই কোড পাওয়া যায়BaseController
/// <summary>
/// returns our standard page not found view
/// </summary>
protected ViewResult PageNotFound()
{
Response.StatusCode = 404;
return View("PageNotFound");
}
তাই বলা হয়
public ActionResult ShowUserDetails(int? id)
{
// make sure we have a valid ID
if (!id.HasValue) return PageNotFound();
এইচটিটিপিএনটফাউন্ডআরেসাল্ট আমি যা ব্যবহার করছি তার একটি দুর্দান্ত প্রথম পদক্ষেপ। এইচটিপিএনটফাউন্ডআরসাল্ট ফিরিয়ে দেওয়া ভাল। তাহলে প্রশ্ন হচ্ছে, এর পরে কী?
আমি হ্যান্ডলনটফাউন্ডএট্রিবিউট নামে একটি অ্যাকশন ফিল্টার তৈরি করেছি যা তারপরে একটি 404 ত্রুটি পৃষ্ঠা দেখায়। যেহেতু এটি একটি দর্শন ফেরায়, তাই আপনি নিয়ামক প্রতি একটি বিশেষ 404 ভিউ তৈরি করতে পারেন বা একটি ডিফল্ট ভাগ করা 404 ভিউ ব্যবহার করা যাক। এমনকি যখন কোনও কন্ট্রোলারের নির্দিষ্ট ক্রিয়া উপস্থিত না থাকে তখনও এটি ডাকা হবে, কারণ ফ্রেমওয়ার্কটি 404 এর স্থিতি কোড সহ একটি এইচটিপিএক্সসেপশন ছুড়ে দেয়।
public class HandleNotFoundAttribute : ActionFilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
var httpException = filterContext.Exception.GetBaseException() as HttpException;
if (httpException != null && httpException.GetHttpCode() == (int)HttpStatusCode.NotFound)
{
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; // Prevents IIS from intercepting the error and displaying its own content.
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.StatusCode = (int) HttpStatusCode.NotFound;
filterContext.Result = new ViewResult
{
ViewName = "404",
ViewData = filterContext.Controller.ViewData,
TempData = filterContext.Controller.TempData
};
}
}
}
মনে রাখবেন যে এমভিসি 3 হিসাবে আপনি কেবল ব্যবহার করতে পারেন HttpStatusCodeResult
।
HttpNotFoundResult
ব্যবহার ActionFilter হয় বজায় রাখা কঠিন কারণ যখনই আমরা একটি ত্রুটি ফিল্টার প্রয়োজন নিক্ষেপ অ্যাট্রিবিউট সেট করতে হবে। আমরা যদি সেট করতে ভুলে যাই? এক উপায় OnException
বেজ কন্ট্রোলারে ডাইরিভ করা হয়। আপনার BaseController
কাছ থেকে প্রাপ্ত একটি সংজ্ঞা দেওয়া দরকার Controller
এবং আপনার সমস্ত কন্ট্রোলার অবশ্যই তা থেকে নেওয়া উচিত BaseController
। বেস কন্ট্রোলার থাকা ভাল অভ্যাস।
Exception
প্রতিক্রিয়া স্থিতি কোডটি 500 ব্যবহার করা হয় তা নোট করুন , সুতরাং আমাদের এটি নট ফাইন্ডের জন্য 404 এবং অননুমোদিতের জন্য 401 এ পরিবর্তন করতে হবে। আমি উপরে যেমন উল্লেখ করেছি ঠিক OnException
তেমন BaseController
ফিল্টার বৈশিষ্ট্য ব্যবহার এড়াতে ওভাররাইড ব্যবহার করুন ।
নতুন এমভিসি 3 ব্রাউজারে একটি খালি ভিউ ফিরিয়ে আরও জটিল করে তোলে। কিছু গবেষণার পরে সর্বোত্তম সমাধানটি আমার উত্তরের উপর ভিত্তি করে তৈরি করা হয়েছে এখানে এএসপি.নেট এমভিসি 3 তে এইচটিপিএনটফাউন্ড () এর জন্য কীভাবে দেখা যায়?
আরও দৃ make় বিশ্বাসের জন্য আমি এটি এখানে আটকান:
কিছু অধ্যয়নের পরে। জন্য কার্যসংক্রান্ত MVC 3 এখানে সব আহরণ করা হয় HttpNotFoundResult
, HttpUnauthorizedResult
, HttpStatusCodeResult
ক্লাস এবং বাস্তবায়ন নতুন (এটা অগ্রাহ্য করা হবে) HttpNotFound
() পদ্ধতি BaseController
।
বেস কন্ট্রোলারটি ব্যবহার করা ভাল অনুশীলন যাতে আপনার প্রাপ্ত সমস্ত কন্ট্রোলারের উপর আপনার 'নিয়ন্ত্রণ' থাকে।
আমি নতুন HttpStatusCodeResult
শ্রেণি তৈরি করেছি , উত্সটি উল্লেখ করে নয়, তবে সম্পত্তি নির্দিষ্ট করে ভিউ বা আপনার পছন্দসই কোনও রেন্ডার করা ActionResult
থেকে । আমি সেটটি সেট করতে আসলটি অনুসরণ করি এবং তারপরে উপযুক্ত ভিউ রেন্ডার করব কারণ আবার আমার থেকে প্রাপ্ত । যথেষ্ট সহজ? এমভিসি কোর এ বাস্তবায়িত হবে আশা করি।ViewResult
View
ViewName
HttpStatusCodeResult
HttpContext.Response.StatusCode
HttpContext.Response.StatusDescription
base.ExecuteResult(context)
ViewResult
আমার BaseController
নমুনা দেখুন :
using System.Web;
using System.Web.Mvc;
namespace YourNamespace.Controllers
{
public class BaseController : Controller
{
public BaseController()
{
ViewBag.MetaDescription = Settings.metaDescription;
ViewBag.MetaKeywords = Settings.metaKeywords;
}
protected new HttpNotFoundResult HttpNotFound(string statusDescription = null)
{
return new HttpNotFoundResult(statusDescription);
}
protected HttpUnauthorizedResult HttpUnauthorized(string statusDescription = null)
{
return new HttpUnauthorizedResult(statusDescription);
}
protected class HttpNotFoundResult : HttpStatusCodeResult
{
public HttpNotFoundResult() : this(null) { }
public HttpNotFoundResult(string statusDescription) : base(404, statusDescription) { }
}
protected class HttpUnauthorizedResult : HttpStatusCodeResult
{
public HttpUnauthorizedResult(string statusDescription) : base(401, statusDescription) { }
}
protected class HttpStatusCodeResult : ViewResult
{
public int StatusCode { get; private set; }
public string StatusDescription { get; private set; }
public HttpStatusCodeResult(int statusCode) : this(statusCode, null) { }
public HttpStatusCodeResult(int statusCode, string statusDescription)
{
this.StatusCode = statusCode;
this.StatusDescription = statusDescription;
}
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
context.HttpContext.Response.StatusCode = this.StatusCode;
if (this.StatusDescription != null)
{
context.HttpContext.Response.StatusDescription = this.StatusDescription;
}
// 1. Uncomment this to use the existing Error.ascx / Error.cshtml to view as an error or
// 2. Uncomment this and change to any custom view and set the name here or simply
// 3. (Recommended) Let it commented and the ViewName will be the current controller view action and on your view (or layout view even better) show the @ViewBag.Message to produce an inline message that tell the Not Found or Unauthorized
//this.ViewName = "Error";
this.ViewBag.Message = context.HttpContext.Response.StatusDescription;
base.ExecuteResult(context);
}
}
}
}
আপনার ক্রিয়াতে এটির মতো ব্যবহার করতে:
public ActionResult Index()
{
// Some processing
if (...)
return HttpNotFound();
// Other processing
}
এবং _ লেআউট.একএসটিএমএলে (মাস্টার পৃষ্ঠার মতো)
<div class="content">
@if (ViewBag.Message != null)
{
<div class="inlineMsg"><p>@ViewBag.Message</p></div>
}
@RenderBody()
</div>
অতিরিক্ত হিসাবে আপনি কোডটিতে মন্তব্য করা মত Error.shtml
নতুন NotFound.cshtml
পছন্দ তৈরি করতে বা পছন্দ করতে পছন্দ করতে পারেন এবং স্থিতির বিবরণ এবং অন্যান্য ব্যাখ্যাগুলির জন্য আপনি একটি ভিউ মডেলটি সংজ্ঞায়িত করতে পারেন।