2010-09-17 64 views
3

是否有可能构建一个混合的ViewResult,它依赖于AjaxRequest或HttpRequest返回PartialViewResultViewResultASP.NET MVC - HybridViewResult(ViewResult/PartialViewResult)

IsAjaxRequest - >返回PartialViewResult IsAjaxRequest! - >返回的ViewResult

据我知道我的HybridViewResult应该ViewResultBase派生。

但是如何实现FindView方法?

+0

为什么不只是有方法返回不同类型取决于''IsAjaxRequest'的ActionResults':,你返回一个视图请求时,会自动复回谐音的任何行动方法? – bzlm 2010-09-17 09:17:54

+0

我在这一方的OP方面,我喜欢返回新的HybridViewResult()。也许命名需要一些工作。 – eglasius 2010-09-17 09:53:48

回答

2

尝试:

public class HybridViewResult : ActionResult 
{ 
    public string ViewName { get; set; } 
    public HybridViewResult() { } 
    public HybridViewResult (string viewName) { this.ViewName = viewName ; } 
    public override void ExecuteResult(ControllerContext context) 
    { 
     if (context == null) throw new ArgumentNullException("context"); 
     var usePartial = ShouldUsePartial(); 
     ActionResult res = GetInnerViewResult(usePartial); 
     res.ExecuteResult(context); 
    } 
    private ActionResult GetInnerViewResult(bool usePartial) 
    { 
     var view = ViewName; 
     ActionResult res; 
     if(String.IsNullOrEmpty(view)) { 
      res = usePartial ? new PartialViewResult(view) : new ViewResult(view); 
     } 
     else { 
      res = usePartial ? new PartialViewResult() : new ViewResult(); 
     } 
     return res; 
    } 
    private bool ShouldUsePartial(ControllerContext context) { 
     return false; //your code that checks if you need to use partial here 
    } 
} 

添加任何构造& GetInnerViewResult变化根据需要即传递模型。

+0

当没有指定视图名称时是否必须手动获取视图名称,或者ASP.NET MVC是否自动获取视图名称? – Rookian 2010-09-17 11:02:35

+0

afaik是从ControllerContext /路由值(即动作).ExecuteResult中确定的,所以是的 - 但我没有测试过它。 /这段代码是基于我所知道的所有这些作品而来的。 – eglasius 2010-09-17 11:09:00

1

在这种情况下,你不能仅仅做出2种不同的动作吗? '共享'的逻辑,你可以简单地把一个[nonAction]方法?

+0

我不介意你,你能详细解释一下你的想法吗? – Rookian 2010-09-17 09:18:00

2

这是对eglasius的答案稍微剥离下来。实际上我正在处理类似的问题,除了我需要返回一个JsonResult。

(未测试)NormalOrAjaxResult只是让您指定非Ajax请求的操作结果,以及针对ajax请求的操作结果。由于这些是ActionResults,因此您可以混用重定向,查看,部分和Json视图结果。

public class NormalOrAjaxResult : ActionResult 
{ 
    private readonly ActionResult _nonAjaxActionResult; 
    private readonly ActionResult _ajaxActionResult; 

    public NormalOrAjaxResult(ActionResult nonAjaxActionResult, ActionResult ajaxActionResult) 
    { 
     _nonAjaxActionResult = nonAjaxActionResult; 
     _ajaxActionResult = ajaxActionResult; 
    } 

    public override void ExecuteResult(ControllerContext context) 
    { 
     var isAjaxRequest = context.HttpContext.Request["isAjax"]; 
     if (isAjaxRequest != null && isAjaxRequest.ToLower() == "true") 
     { 
      _ajaxActionResult.ExecuteResult(context);  
     } else 
     { 
      _nonAjaxActionResult.ExecuteResult(context); 
     } 
    } 
} 
+0

+1虽然我个人喜欢返回新的HybridViewResult()多于返回HybridViewResult(View(),PartialView())。此外,与控制器的基地,它可以返回HybridView():) – eglasius 2010-09-17 10:47:16

+0

HybridViewResult看起来更好看,虽然与NormalOrAjaxResult你有一个更明确的指示返回什么。 – Castrohenge 2010-09-17 10:52:18

+0

,但它仍然可以命名为NormalOrAjaxResult并自动执行/或在此情况下为NormalOrPartialViewResult。 – eglasius 2010-09-17 11:11:09

1

我知道我真的迟到了这里,但这些没有似乎相当合理了我,所以这里是我的2美分:

public class PartialViewConverter : ViewResult 
{ 
    public ViewResultBase Res { get; set; } 
    public PartialViewConverter(ViewResultBase res) { Res = res; } 
    public override void ExecuteResult(ControllerContext context) 
    { 
     Res.ExecuteResult(context); 
    } 
    public static ViewResult Convert(ViewResultBase res) 
    { 
     return new PartialViewConverter(res); 
    } 
} 

的使用方式:

return PartialViewConverter.Convert(PartialView()); 

然后在您的控制器中,如果您覆盖查看

protected override ViewResult View(string viewName, string masterName, object model) 
{ 
    //Whichever condition you like can go here 
    if (Request.QueryString["partial"] != null) 
     return PartialViewConverter.Convert(PartialView(viewName, model)); 
    else 
     return base.View(viewName, masterName, model); 
} 
public ActionResult Index() 
{ 
    ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application."; 

    //This will return a partial if partial=true is passed in the querystring. 
    return View(); 
}