How to Return partial view of another controller by controller?

前端 未结 3 709
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-04 07:58

I have an XXX.cshtml file in a Views\\ABC folder. Its controller is ABC

I also have an action method in my DEF co

相关标签:
3条回答
  • 2020-12-04 08:40

    The control searches for a view in the following order:

    • First in shared folder
    • Then in the folder matching the current controller (in your case it's Views/DEF)

    As you do not have xxx.cshtml in those locations, it returns a "view not found" error.

    Solution: You can use the complete path of your view:

    Like

     PartialView("~/views/ABC/XXX.cshtml", zyxmodel);
    
    0 讨论(0)
  • 2020-12-04 08:47

    Normally the views belong with a specific matching controller that supports its data requirements, or the view belongs in the Views/Shared folder if shared between controllers (hence the name).

    "Answer" (but not recommended - see below):

    You can refer to views/partial views from another controller, by specifying the full path (including extension) like:

    return PartialView("~/views/ABC/XXX.cshtml", zyxmodel);
    

    or a relative path (no extension), based on the answer by @Max Toro

    return PartialView("../ABC/XXX", zyxmodel);
    

    BUT THIS IS NOT A GOOD IDEA ANYWAY

    *Note: These are the only two syntax that work. not ABC\\XXX or ABC/XXX or any other variation as those are all relative paths and do not find a match.

    Better Alternatives:

    You can use Html.Renderpartial in your view instead, but it requires the extension as well:

    Html.RenderPartial("~/Views/ControllerName/ViewName.cshtml", modeldata);
    

    Use @Html.Partial for inline Razor syntax:

    @Html.Partial("~/Views/ControllerName/ViewName.cshtml", modeldata)
    

    You can use the ../controller/view syntax with no extension (again credit to @Max Toro):

    @Html.Partial("../ControllerName/ViewName", modeldata)
    

    Note: Apparently RenderPartial is slightly faster than Partial, but that is not important.

    If you want to actually call the other controller, use:

    @Html.Action("action", "controller", parameters)
    

    Recommended solution: @Html.Action

    My personal preference is to use @Html.Action as it allows each controller to manage its own views, rather than cross-referencing views from other controllers (which leads to a large spaghetti-like mess).

    You would normally pass just the required key values (like any other view) e.g. for your example:

    @Html.Action("XXX", "ABC", new {id = model.xyzId })
    

    This will execute the ABC.XXX action and render the result in-place. This allows the views and controllers to remain separately self-contained (i.e. reusable).

    Update Sep 2014:

    I have just hit a situation where I could not use @Html.Action, but needed to create a view path based on a action and controller names. To that end I added this simple View extension method to UrlHelper so you can say return PartialView(Url.View("actionName", "controllerName"), modelData):

    public static class UrlHelperExtension
    {
        /// <summary>
        /// Return a view path based on an action name and controller name
        /// </summary>
        /// <param name="url">Context for extension method</param>
        /// <param name="action">Action name</param>
        /// <param name="controller">Controller name</param>
        /// <returns>A string in the form "~/views/{controller}/{action}.cshtml</returns>
        public static string View(this UrlHelper url, string action, string controller)
        {
            return string.Format("~/Views/{1}/{0}.cshtml", action, controller);
        }
    }
    
    0 讨论(0)
  • 2020-12-04 08:47

    Simply you could use:

    PartialView("../ABC/XXX")
    
    0 讨论(0)
提交回复
热议问题