2012-09-11 11 views
7

私は、城ウィンザーファクトリを使用してリクエストURLに基​​づいてオブジェクトをインスタンス化しています。どのように応答を終了し、HTTPコード404を送り返すことができますか?

ような何か:いくつかのケースでは

public FooViewModel Get() 
    { 
     if (HttpContext.Current == null) 
     { 
      return new FooViewModel(); 
     } 

     var currentContext = new HttpContextWrapper(HttpContext.Current); 

     // resolve actual view model. 

、私は実際に404を投げると、要求を停止する、現在のように:

 throw new HttpException(404, "HTTP/1.1 404 Not Found"); 
     currentContext.Response.End(); 

要求がまだ終了していませんがアクションに当たってビューを解決しようとしていますか?私はこのすべて間違っについて

public class HomeController : Controller 
{ 
    public FooViewModel Foo { get; set; } 

    public ActionResult Index() 
    { 
     ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application."; 

     return View(); 
    } 

を考えています:

私のコントローラは、次のようになりますか?それとも私がこれを達成する方法はありますか?

私が考えていた代替案は、Fooプロパティの状態を確認するアクションの属性ですか?

public class RequiresModelAttribute : ActionFilterAttribute 
{ 
    private readonly string _modelName; 

    public RequiresModelAttribute(string modelName) 
    { 
     _modelName = modelName; 
    } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     var property = filterContext.Controller.GetType().GetProperty(_modelName); 
     var model = property.GetValue(filterContext.Controller); 
     if (model == null) 
     { 
      filterContext.Result = new HttpStatusCodeResult(404); 
     } 
    } 
} 

を次に、あなたが行うことができ、あなたのコントローラ上:

答えて

6

私はアクションフィルタを使用してのアプローチは、あなたが望んでいるものを達成できると思い

public class HomeController : Controller 
{ 
    public FooViewModel Foo { get; set; } 

    [RequiresModel("Foo")] 
    public ActionResult Index() 
    { 
     ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application."; 

     return View(); 
    } 
} 

編集:おそらくグローバルフィルタを使用してスローされたHttpExceptionsを尊重するには?

public class HonorHttpExceptionAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     var httpException = filterContext.HttpContext.AllErrors.FirstOrDefault(x => x is HttpException) as HttpException; 
     if (httpException != null) 
     { 
      filterContext.Result = new HttpStatusCodeResult(httpException.GetHttpCode()); 
     } 
    } 
} 

はその後Global.asaxの中で:

public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
    { 
     filters.Add(new HandleErrorAttribute()); 
     filters.Add(new HonorHttpExceptionAttribute()); 
    } 
+0

私はこれを既にこれに変更しました。他の提案があるかどうか確認してください。 – shenku

+0

@shenku私は別のアプローチで自分のレスポンスを更新しました。おそらく、あなたのシナリオでうまくいくでしょうか? –

2

別のオプションは、コントローラ上onExceptionをオーバーライドしています。

public ActionResult Index() 
    { 
     ViewBag.Message = "Welcome to ASP.NET MVC!"; 
     Get(); 
     return View(); 
    } 

    public int Get() 
    { 
     throw new HttpException(404, "HTTP/1.1 404 Not Found"); 
     // we don't need end the response here, we need go to result step 
     // currentContext.Response.End(); 

    } 

    protected override void OnException(ExceptionContext filterContext) 
    { 
     base.OnException(filterContext); 
     if (filterContext.Exception is HttpException) 
     { 
      filterContext.Result = this.HttpNotFound(filterContext.Exception.Message); 
     } 
    } 
関連する問題