MVC Razor 隐藏输入和传递值

Posted

技术标签:

【中文标题】MVC Razor 隐藏输入和传递值【英文标题】:MVC Razor Hidden input and passing values 【发布时间】:2012-07-04 18:04:09 【问题描述】:

我很确定我在这里做错了什么。在过去的两个月里,我们一直在使用 MVC 和 Razor 开发一个 Web 应用程序,我们从未想过使用表单元素。现在已经对母版页和子页做了很多工作,这意味着重组我们的大部分代码以使用表单元素,这将导致页面上有多个表单元素。

除此之外,在 Asp.Net 中,如果我想访问后面 C# 代码中的任何控件,我可以给它一个 ID="SomeID" 和一个 RUNAT="SERVER"。然后在我后面的代码中我可以设置它的值和属性。

当我在 Razor 中执行此操作时,我们使用如下行:

 <input id="hiddenPostBack" runat="server" type="hidden" />

为什么我不能在控制器中访问它?如果是第一次加载页面,我想检测回发并将值设置为 false,如果不是,则将值设置为 true。然后基于此,我将在服务器端或客户端读取它并做一些事情。

我真正的问题是,鉴于我没有表单元素,我如何在服务器端和客户端“做某事”。我的印象是,如果我想将值从客户端传递到服务器并返回,最简单的方法是使用隐藏输入。但我只是不知道如何使用 MVC3 和 razor 来实现这一点。

提前感谢您的帮助。

【问题讨论】:

MVC 中没有托管的“回发”。您需要使用 javascript 来管理客户端的操作... 【参考方案1】:

从 WebForms 迁移到 MVC 需要对逻辑和大脑处理进行彻底的改变。您不再与服务器端和客户端的“表单”交互(事实上,即使使用 WebForms,您也没有与客户端交互)。您可能只是在这里混淆了一些想法,因为使用 WebForms 和 RUNAT="SERVER" 您只是在与网页的建筑物进行交互。

MVC 有点相似,因为您有构建模型的服务器端代码(构建用户将看到的数据所需的数据),但是一旦构建了 html,您需要了解服务器之间的链接并且用户不再存在。他们有一个 HTML 页面,就是这样。

所以您正在构建的 HTML 是只读的。您将模型传递到 Razor 页面,该页面将构建适合该模型的 HTML。

如果你想要一个隐藏元素,它根据这是否是第一个视图来设置真或假,你需要在你的模型中设置一个布尔值,如果它是为了响应后续操作,则在动作中将其设置为真.这可以通过根据请求是 [HttpGet] 还是 [HttpPost] 执行不同的操作来完成(如果这适合您设置表单的方式:第一次访问的 GET 请求和提交表单的 POST 请求)。

或者,模型可以在创建时设置为 True(这将是您第一次访问该页面),但 您检查该值是 True 还是 False(因为 bool 默认实例化时为 False)。然后使用:

@Html.HiddenFor(x => x.HiddenPostBack)

在你的表格中,这将把一个隐藏的True。当表单被发送回您的服务器时,模型现在将该值设置为 True。

很难提供比这更多的建议,因为您的问题并未具体说明为什么您要这样做。阅读一本关于从 WebForms 迁移到 MVC 的好书可能很重要,例如 Steve Sanderson 的 Pro ASP.NET MVC。

【讨论】:

我同意,我确实需要一本好书。然而,我们是第一次发布,只是想尽快推出一些东西,所以正如解释的那样,重写页面以正确使用表单目前不切实际,但稍后它将是确定的。您的建议在某种程度上比我所看到的要好,但它仍然采用模型和控制器/操作结果的方法来处理视图页面上的每个控件。我正在使用下拉组合框和复选框或收音机的单击事件以及偶尔的按钮回帖。但是javascript处理重定向。感谢您的建议。 我知道这是一个非常古老的答案,但我仍然得到分数,所以它显然仍然很有趣。我只是想补充一点,您需要确保将“HiddenPostBack”值的设置器设置为公开的,否则模型绑定器不会设置它。这让我昨天发现了。例如,public bool HiddenPostBack get;放; 【参考方案2】:

如果您使用的是 Razor,则无法直接访问该字段,但可以管理其值。

这个想法是,第一个 Microsoft 方法使开发人员远离 Web 开发,并使桌面程序员(例如)更容易制作 Web 应用程序。

同时,Web 开发人员并不了解 ASP.NET 这种棘手的奇怪方式。

实际上,这个隐藏的输入是在客户端呈现的,而 ASP 无法访问它(它从来没有)。但是,随着时间的推移,您会看到它是一种盗版方式,并且当您使用它时,您可能会依赖它。 Web 开发不同于桌面或移动。

模型是您的逻辑单元,隐藏字段(以及整个视图页面)只是数据的代表视图。因此,您可以将您的工作专门用于应用程序或域逻辑,而视图只是将其提供给消费者 - 这意味着您不需要视图中的详细访问和“头脑风暴”功能。

控制器确实可以管理隐藏或常规设置。模型提供特定的逻辑单元属性和功能,而视图只是将其呈现给最终用户,简单地说。阅读有关MVC 的更多信息。

型号

public class MyClassModel

    public int Id  get; set; 
    public string Name  get; set; 
    public string MyPropertyForHidden  get; set; 

这是控制器动作

public ActionResult MyPageView()

    MyClassModel model = new MyClassModel(); // Single entity, strongly-typed
    // IList model = new List<MyClassModel>(); // or List, strongly-typed
    // ViewBag.MyHiddenInputValue = "Something to pass"; // ...or using ViewBag

    return View(model);

下面是视图

//This will make a Model property of the View to be of MyClassModel
@model MyNamespace.Models.MyClassModel // strongly-typed view
// @model IList<MyNamespace.Models.MyClassModel> // list, strongly-typed view

// ... Some Other Code ...

@using(Html.BeginForm()) // Creates <form>

    // Renders hidden field for your model property (strongly-typed)
    // The field rendered to server your model property (Address, Phone, etc.)
    Html.HiddenFor(model => Model.MyPropertyForHidden); 

    // For list you may use foreach on Model
    // foreach(var item in Model) or foreach(MyClassModel item in Model)


// ... Some Other Code ...

带有 ViewBag 的视图:

// ... Some Other Code ...

@using(Html.BeginForm()) // Creates <form>

    Html.Hidden(
        "HiddenName",
        ViewBag.MyHiddenInputValue,
        new  @class = "hiddencss", maxlength = 255 /*, etc... */ 
    );


// ... Some Other Code ...

我们正在使用 Html Helper 来呈现隐藏字段,或者我们可以手动编写它 - &lt;input name=".." id=".." value="ViewBag.MyHiddenInputValue"&gt; 也。

ViewBag 是视图的某种数据载体。它不限制你使用模型 - 你可以放置任何你喜欢的东西。

【讨论】:

这就是我提到 Razor 示例的原因。 @Francis 不知道 MVC 和 Webforms 之间的区别。 Razor 或 ASPX 视图引擎无关紧要,因为他可以在 MVC 中使用 ASPX 视图引擎,但仍然面临完全相同的问题。 我经常遇到这个想法。然而,我很难相信我应该为我的视图页面上的每个控件创建一个新的模型和/或控制器操作结果。即使可能有多个控制器用于页面或页面上的控件有多个操作结果(据我所知不是,但我愿意犯错),我如何在相关控制人。我对这种方法感到困惑,但感谢您的回答。【参考方案3】:

您可能已经想到,Asp.Net MVC 是不同于 Asp.Net(webforms)的范式。在 Asp.Net MVC 中访问服务器和客户端之间的表单元素采用不同的方法。

您可以在网上搜索更多关于此的阅读材料。现在,我建议使用 Ajax 来获取或发布数据到服务器。您仍然可以使用 input type="hidden",但使用来自 ViewData 或 Razor 的值初始化它,ViewBag

例如,您的控制器可能如下所示:

public ActionResult Index()

     ViewBag.MyInitialValue = true;
     return View();
 

在您看来,您可以拥有一个由ViewBag 中的值初始化的输入元素:

<input type="hidden" name="myHiddenInput" id="myHiddenInput" value="@ViewBag.MyInitialValue" />

然后你可以通过ajax在客户端和服务器之间传递数据。例如,使用 jQuery:

$.get('GetMyNewValue?oldValue=' + $('#myHiddenInput').val(), function (e) 
   // blah
);

您可以根据需要使用$.ajax$.getJSON$.post

【讨论】:

我了解您的建议不是标准的 MVC 做事方式。但我最初正在寻找一种快速而肮脏的方法,我会给你的例子更多的教导。稍后,当时间允许时,我会将我的解决方案重新编程为一个更好的标准,但现在我需要把它拿出来。我还不确定,但这可能是我一直在寻找的答案。 试试看。我一直在为其他一些东西这样做,但出于您的目的,它也可能是可行的。这不一定是最佳实践,但 MVC 并不禁止使用 Ajax。只是不要广泛使用这种技术。【参考方案4】:

首先,ASP.NET MVC 的工作方式与 WebForms 不同。你没有完整的runat="server" 东西。 MVC 不提供 WebForms 提供的抽象层。可能您应该尝试了解控制器和操作是什么,然后您应该查看模型绑定。任何关于 MVC 的初级教程都展示了如何在客户端和服务器之间传递数据。

【讨论】:

我认为你可以在 MVC 中使用 ASP 表单。视图引擎选项在 Razor CSHTML 或 ASP Web 窗体之间。 你确实可以,但是你有没有注意到这样的表格不再有代码了。 :-)(可以理解,因为控制器是后面的新代码)。谢谢你的回答。【参考方案5】:

您做错了,因为您尝试在 MVC 应用程序中映射 WebForms。

MVC 中没有服务器端控件。只有 View控制器在后端。您通过以下方式将数据从服务器发送到客户端 使用模型初始化视图的方法。

这发生在对您的资源的 HTTP GET 请求上。

[HttpGet]
public ActionResult Home() 

  var model = new HomeModel  Greeatings = "Hi" ;
  return View(model);

您通过将数据发布到服务器来将数据从客户端发送到服务器 服务器。为了实现这一点,您在视图中创建一个表单并 [HttpPost] 控制器中的处理程序。

// View

@using (Html.BeginForm()) 
  @Html.TextBoxFor(m => m.Name)
  @Html.TextBoxFor(m => m.Password)


// Controller

[HttpPost]
public ActionResult Home(LoginModel model) 

  // do auth.. and stuff
  return Redirect();

【讨论】:

以上是关于MVC Razor 隐藏输入和传递值的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Asp.net MVC Razor 将隐藏字段值从一个控制器传递到另一个控制器

MVC 5 Razor 视图未将 bool 绑定到输入

在 MVC/Razor 中,如何获取多个复选框的值并将它们全部传递给控制器​​?

通过隐藏变量传递复杂的 json 并在 mvc 3 控制器中读取

动态读取输入 Razor MVC C#

如何在Razor中设置隐藏值