【问题标题】:ASP.NET MVC - HybridViewResult (ViewResult /PartialViewResult)ASP.NET MVC - HybridViewResult (ViewResult /PartialViewResult)
【发布时间】:2011-04-13 15:17:08
【问题描述】:

是否可以构建一个混合 ViewResult 以依赖 AjaxRequest 或 HttpRequest 返回 PartialViewResultViewResult

IsAjaxRequest --> 返回 PartialViewResult !IsAjaxRequest --> 返回视图结果

据我所知,我的 HybridViewResult 应该派生自 ViewResultBase。

但是如何实现 FindView 方法呢?

【问题讨论】:

  • 为什么不让方法根据IsAjaxRequest返回不同类型的ActionResults
  • 我支持 OP,我喜欢返回新的 HybridViewResult()。也许命名需要一些工作。

标签: c# asp.net asp.net-mvc viewresult


【解决方案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());

如果你覆盖 View,然后在你的控制器中

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();
}

【讨论】:

    【解决方案2】:

    这是对 eglasius 答案的稍微精简的看法。我实际上正在解决一个类似的问题,只是我需要返回一个 JsonResult。

    (未经测试的)NormalOrAjaxResult 只是让您为非 ajax 请求指定一个操作结果,为 ajax 请求指定一个操作结果。因为这些是 ActionResult,您可以混合使用 Redirect、View、Partial 和 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);
            }
        }
    }
    

    【讨论】:

    • +1 虽然我个人更喜欢返回新的 HybridViewResult() 而不是返回 HybridViewResult(View(), PartialView())。也有一个控制器基础,它可以返回 HybridView() :)
    • HybridViewResult 看起来更好看,尽管使用 NormalOrAjaxResult 您可以更明确地指示返回的内容。
    • 但它仍然可以命名为 NormalOrAjaxResult 并自动/或在本例中为 NormalOrPartialViewResult。
    • .. 用于检查 ajax 请求使用 context.HttpContext.Request.IsAjaxRequest() 并且你的字符串会飞走 ​​xD,你的方法也很好,但我更喜欢混合 ViewResult :)
    • 非常感谢 IsAjaxRequest() 提示,我从来不知道。良好的全方位学习经验问题。
    【解决方案3】:

    试试:

    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 变体,即传递模型。

    【讨论】:

    • 当没有指定视图名称时,我必须手动获取视图名称还是 ASP.NET MVC 自动获取视图名称?
    • afaik 由 ControllerContext / 路由值(即操作)在 .ExecuteResult 中确定,所以是的 - 但我还没有测试过。 / 根据我对所有这些片段的了解,该代码来自我的脑海中。
    【解决方案4】:

    在这种情况下,你不能只做 2 个不同的动作吗?您可以简单地将“共享”逻辑放入 [nonAction] 方法中?

    【讨论】:

    • 我不明白你的意思,你能详细解释一下你的想法吗?
    猜你喜欢
    • 1970-01-01
    • 2012-01-24
    • 1970-01-01
    • 2010-11-13
    • 1970-01-01
    • 1970-01-01
    • 2012-05-18
    • 1970-01-01
    • 2013-11-29
    相关资源
    最近更新 更多