【问题标题】:View not found - asp.net mvc error查看未找到 - asp.net mvc 错误
【发布时间】:2011-08-05 14:59:37
【问题描述】:

我收到一条错误消息,提示尚未找到视图更新,我想显示 TaskDetail 视图而不是更新视图...

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Update(int taskid, string status)
    {
        if (!status.Equals("closed", StringComparison.OrdinalIgnoreCase) &&
            !status.Equals("opened", StringComparison.OrdinalIgnoreCase))
            ModelState.AddModelError("", "incorrect status, please try again");

        if (!this.ModelState.IsValid)
            return TaskDetail(taskid);

        if (status.Equals("Closed", StringComparison.OrdinalIgnoreCase))
            _service.CloseTask( taskid, true);
        else
            _service.CloseTask(taskid, false);

        this.FlashInfo("success, task status has been updated...");
        return RedirectToAction("TaskDetail");

}

例外:

$exception{"The view 'Update' or its master was not found. The following locations were searched:\r\n~/Areas/Tasks/Views/TaskManager/Update.aspx\r\n~/Areas/Tasks/Views/TaskManager/Update.ascx\r\n~/Areas/Tasks/Views/Shared/Update.aspx\r\n~/Areas/Tasks/Views/Shared/Update.ascx\r\n~/Views/TaskManager/Update.aspx\r\n~/Views/TaskManager/Update.ascx\r\n~/Views/Shared/Update.aspx\r\n~/Views/Shared/Update.ascx"} System.Exception {System.InvalidOperationException}

任务详情:(这是在同一个控制器内)

    [HttpGet]
    public ActionResult TaskDetail(int taskid)
    {
        var loggedonuser = _repo.GetCurrentUser();


        var companies = _repo.All<Company>();
        var users = _repo.All<User>();

        var task = _repo.Single<InstructionTask>
            (x => x.TaskID == taskid && (x.CompanyID == loggedonuser.CompanyID || x.AssignedTo.Contains(loggedonuser.CompanyType.ToString())));

        var dto = new TaskDTO
        {
            TaskID = task.TaskID,
            Title = task.Title,
            Description = task.Description,
            DateCreated = task.DateCreated,
            IsClosed = task.IsClosed,
            CompanyID = companies.Where(y => task.CompanyID == y.CompanyID).SingleOrDefault().Identifier,
        };

        var checkedtags = TaskTagsHelper.GetTags(task.AssignedTo);

        var t = TaskTagsHelper.GetPanelTags();

        if (checkedtags != null) //if tags are present only then tick them off...
        {
            foreach (var item in t.Keys.ToList())
            {
                if (checkedtags.Any(x => x == item))
                    t[item] = true;
            }
        }

        dto.AvailableTags = t;

        if (task.DueDate.HasValue)
            dto.DueDate = task.DueDate.Value;

        var comments = _repo.All<TaskComment>()
            .Where(x => x.TaskID == task.TaskID)
            .OrderByDescending(x => x.Timestamp)
            .Select(x => new TaskCommentDTO
            {
                Comment = x.Comment,
                Timestamp = x.Timestamp,
                CompanyID = companies.Where(y => x.CompanyID == y.CompanyID).SingleOrDefault().Identifier,
                UserID = users.Where(y => x.UserID == y.UserID).SingleOrDefault().Login,
                Type = EnumHelper.Convert<TaskCommentType>(x.Type)
            });

        dto.AllComments = comments;

        return View(new TaskViewModel
        {
            TaskDetail = dto,
            NewComment = new TaskCommentDTO()
        });
    }

我在我的基本控制器中发现了异常:

    //Generic methods/ controllers/ attributes will be applied here...
    protected override void OnException(ExceptionContext filterContext)
    {
        //dont interfere if the exception is already handled
        if (filterContext.ExceptionHandled)
            return;

        //let the next request know what went wrong
        filterContext.Controller.TempData["exception"] = filterContext.Exception;

        //logg exception

        //set up redirect to my global error handler
        filterContext.Result = new ViewResult { ViewName = "~/Views/Error/PublicError.aspx" };

        //advise subsequent exception filters not to interfere and stop
        // asp.net from showing yellow screen of death
        filterContext.ExceptionHandled = true;

        //erase any output already generated
        filterContext.HttpContext.Response.Clear();
    }

【问题讨论】:

    标签: c# asp.net-mvc-2 view error-handling


    【解决方案1】:

    根据我对您代码的理解,您正在从 Update 方法调用 TaskDetail 操作。不建议这样做。原因如下:

    1. 请求的所属上下文是 Update 方法,这就是它尝试呈现“Update”视图的原因。这是因为按照惯例,视图是根据被击中的第一个动作来选择的。 MVC 不知道您调用了 TaskDetail。
    2. 这违反了 PRG 模式 (Post-Redirect-Get)。我建议您在此处阅读此内容:http://en.wikipedia.org/wiki/Post/Redirect/Get - 基本上,您真的不应该从 HTTP POST 中呈现任何内容。您应该重定向回 GET。不这样做会导致各种问题。

    如果您希望它按原样工作,您可以通过将 TaskDetail 的最后一行更改为以下内容来做到这一点,以便它知道始终呈现 TaskDetail 视图,但我不建议这样做:

    return View("TaskDetail", ...viewModel...)
    

    【讨论】:

    • 如果我进行重定向,我将如何填充模型状态错误?错误丢失了对吗?模型状态再次变为“有效”,可以这么说???
    • 如果您的模型状态无效,您不会进行重定向。您只需再次向他们展示表单即可。
    • 您应该将 ModelState 放入 TempData,然后重定向到 GET 并恢复它。有一个完整的框架可以为您处理此处描述的所有内容,因此您不必担心自己管理它:weirdlover.com/2010/07/21/…
    • 基本上,您的 TaskDetail 视图将具有与之关联的 TaskDetailViewModel 强类型模型之类的东西。在您的 TaskDetail 控制器操作中,它将填充此模型并将其返回到视图,例如:TaskDetailViewModel model = new TaskDetailViewModel();返回视图(模型);如果您的模型状态在 POST to Update 上无效,您只需重新创建模型并返回视图,但由于您正在 POST 到 Update,您需要指定视图:return View("TaskDetail", model) ;
    • @Dismissile:你错了。您应该将其放入 TempData 并重定向。如果你按下 F5 会发生什么,或者如果你在 POST 动词期间渲染一些东西,会发生什么?玩玩看看。
    【解决方案2】:

    那么显而易见的问题是:

    您在以下文件夹之一中有文件吗:

    Views\ControllerName\TaskDetail.aspx
    Views\ControllerName\TaskDetail.ascx
    Views\Shared\TaskDetail.aspx
    Views\Shared\TaskDetail.ascx
    

    其中 ControllerName 是您的 Update 方法所在的控制器的名称。也就是说,如果您的控制器是 HomeController,那么您的文件夹就是 \Views\Home\

    编辑:
    我对您的 ModelState.IsValid 调用也有些困惑,但主要是因为您没有包含 TaskDetail 控制器操作。如果您的模型状态无效,您是否不想返回更新视图以便用户可以更正错误并重新提交?还是他们从 TaskDetail POST 到 Update 操作?

    【讨论】:

    • 是的,他们正在从 TaskDetail 发布到 Update,TaskDetail 是 Get 请求,其中可能会发生多个表单发布,例如UpdateTask, AddComment... 我确实有查看 TaskDetail
    • 好的,这个异常发生在哪里。是在 RedirectToAction 调用上失败还是在 TaskDetail 调用上失败?是 AJAX 调用还是常规请求失败?
    • 这是一个简单的 FormPost,令人惊讶的错误仅在 Exception 的基本控制器内部被捕获(参见上面的代码)...
    • 我的意思是异常的来源。是因为 RedirectToAction 调用还是发生在 return TaskDetail() 调用或其他地方?它是在每种情况下都失败还是仅在一条路径中失败。可能有助于缩小问题范围。
    • 会发生什么:当模型状态无效时'return TaskDetail(taskid);'运行,没有发生异常,代码成功调用任务详细信息的get请求,完成所有工作并毫无失败地到达方法的末尾,我继续单步执行代码,没有发生任何有趣的事情/甚至没有抛出异常,然后我到达基本控制器 OnException 我可以在 filtercontext 中看到错误...
    猜你喜欢
    • 2015-10-18
    • 1970-01-01
    • 2014-11-13
    • 2015-09-22
    • 2019-02-19
    • 2016-09-05
    • 1970-01-01
    • 1970-01-01
    • 2012-03-06
    相关资源
    最近更新 更多