Asp.Net MVC 5 如何将 ViewBag 发送到局部视图?

7

我有一个_LoginPartial视图,希望通过ViewBag向其发送数据,但我发送数据的控制器没有视图。

public PartialViewResult Index()
    {
        ViewBag.sth = // some data
        return PartialView("~/Views/Shared/_LoginPartial.cshtml");
    }

这段代码对我没有用。

你在 _LoginPartial 视图中访问了 @ViewBag.sth 吗?这应该可以工作。 - trailmax
1
创建一个模型并将其传递给部分视图。使用 ViewBag 不是最佳实践。 - trailmax
@CanTunç 我需要知道你在哪里和如何使用它,以便提出替代方案。它是在另一个视图中呈现吗?它是在另一个控制器操作中呈现吗?还是通过 AJAX 获取的? - Radu Porumb
我在Partial View中使用它,它只包含一个菜单用于显示已登录用户,并且我将其呈现在主Layout上。 - user3856966
<body> <div> <ul>..</ul> @Html.Partial("_LoginPartial") </div> </body> <body> <div> <ul>..</ul> @Html.Partial("_LoginPartial") </div> </body> - user3856966
显示剩余4条评论
4个回答

7
似乎您预期的是当您执行@Html.Partial('_LoginPartial')时会调用此Index操作。这是不可能发生的。Partial只是将局部视图通过Razor 与当前视图上下文一起运行并输出生成的HTML。
如果您需要为局部视图提供其他信息,可以指定自定义的ViewDataDictionary
@Html.Partial("_LoginPartial", new ViewDataDictionary { Foo = "Bar" });

然后你可以通过以下方式在partial中访问:

ViewData["Foo"]

您还可以使用子操作,如果您正在使用不需要主视图上下文的部分视图,则通常更可取。 _LoginPartial 看起来是一个很好的候选项,尽管我不确定您如何使用它。然而,具有单独身份验证的默认MVC项目使用子操作的 _LoginPartial 视图。

基本上,您已经拥有的代码已经可以工作,您只需要更改如何引用它,改为使用 Html.Action 而不是 Html.Partial

@Html.Action("Index")

请注意,您现在调用的是 动作 而不是视图。

6
这是对我有效的方法:@Html.Partial("_LoginPartial", new ViewDataDictionary {{"Foo ", "Bar"}, {"Foo2", "Bar2"}}) - Nerdroid

0

您可以直接将数据传递给局部视图。

public PartialViewResult Index()
{
    var data = // some data
    return PartialView("~/Views/Shared/_LoginPartial.cshtml", data);
}

传递多个数据(pieces of data)

public class MyModel
{
    public int Prop1 { get; set; }
    public int Prop2 { get; set; }
}

public PartialViewResult Index()
{
    var data = new MyModel(){ Prop1 = 5, Prop2 = 10 };
    return PartialView("~/Views/Shared/_LoginPartial.cshtml", data);
}

能否发送多个数据? - user3856966
2
答案在问题的上下文中不正确。确实,您可以使用模型传递数据。但问题是要在Viewbag中传递数据。 - codingpirate
1
@trailmax 我同意你的建议,但问题是关于在Viewbag中设置数据而不是在模型中传递数据。Down是因为它不是这个问题的解决方案。如果问题是如何在View中传递数据,我同意上面提到的解决方案。 - codingpirate
1
@kumarharsh,请再次阅读有关XY问题的内容。 - jamesSampica
你在Partial View中指定了它所使用的模型吗? - jamesSampica
显示剩余3条评论

0
我将viewBag数据传递给了我的局部视图,如下所示,并且在我的局部视图中使用@Html.Raw(Json.Encode(ViewBag.Part))将该viewBag数据对象转换为JSON。
下面是我的代码示例。
 public async  Task<ActionResult> GetJobCreationPartialView(int id)
        {
            try
            {
                var client = new ApiClient<ServiceRepairInspectionViewModel>("ServiceRepairInspection/GetById");
                var resultdata = await client.Find(id);

                var client2 = new ApiClient<PartViewModel>("Part/GetActive");  
                var partData = await client2.FindAll(); 

                var list = partData as List<PartViewModel> ?? partData.ToList();
                ViewBag.Part = list.Select(x => new SelectListItem() {Text = x.PartName, Value = x.Id.ToString()});
                return PartialView("_CreateJobCardView" ,resultdata);
            }
            catch (Exception)
            {

                throw;
            }

        }

这里我已经传递了模型和视图数据。


-1

首先,你提供的代码无法运行。当你使用@Html.Partial("_SomeView")时,你所拥有的Index()方法不会运行。所有@Html.Partial("_SomeView")做的就是在当前视图中使用当前视图的ViewContext呈现_SomeView.cshtml

为了使其工作,你需要一些在项目中所有控制器中都通用的功能。你有两个选择:为ControllerBase编写扩展方法或创建一个BaseController,让项目中的所有控制器都继承它。

扩展方法:

帮助程序:

public static class ControllerExtensions
{
    public static string GetCommonStuff(this ControllerBase ctrl)
    {
        // do stuff you need here
    }
}

视图:

@ViewContext.Controller.GetCommonStuff()

基础控制器

控制器:

public class BaseController : Controller
{
    public string GetCommonStuff()
    {
        // do stuff you need here
    }
}

其他控制器:

public class SomeController : BaseController
...
...

视图:

@((ViewContext.Controller as BaseController).GetCommonStuff()) 

-1 直接从视图调用控制器方法绝对不是使用任何MVC框架的正确方式。请不要向他人推荐这种做法。 - ZolaKt
@ZolaKt 这很公平。您能告诉我您将如何解决这个用户的问题吗? - Radu Porumb
可能有无数种解决方法,但我同意其他答案评论区大多数人的说法。使用ViewBag通常是一个不好的主意。创建ViewModel,并将其作为Model进行传递,不要使用ViewBag和/或ViewData。它们是微软虚构的概念,在任何干净的MVC框架中都不应该存在,甚至在像.NET这样的强类型框架中也不应该存在。如果您不想重复代码,可以始终创建一个基础控制器和一个基础ViewModel,并在基础控制器中填充“公共”的内容。 - ZolaKt
如果没有其他选择,使用ViewBag / ViewData会破坏使用强类型语言(如C#)的最大优势,即重构。这意味着,您可以简单地查找某个属性的所有引用,重命名它或进行其他操作...使用ViewBags的“查找引用”的唯一方法是通过属性名称比较,这显然会导致问题。即使Resharper也经常迷失在其中。如果您想要“无处不在的动态性”,那么根本没有使用.NET的意义,您只是在“攻击风车”。现在有很多出色的动态语言可供选择。 - ZolaKt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接