如何在Razor中设置隐藏值

41

我知道我现在尝试的做法不太好,但是我有一些特殊的限制。

我有多个站点,使用相同的MVC3代码库。其中一个站点的要求是从表单中隐藏一些必填字段。

我知道最好的方法是修改控制器以设置这些字段的默认值,但我想只修改此特定站点的视图而不改变代码来实现此目的。

那么,在视图中如何将特定模型属性设置为默认值?理想情况应该是这样的:

@Html.HiddenFor(model => model.RequiredProperty)
@model.RequiredProperty = "default"

编辑:更多解释

实际上,这是在子视图中,该子视图由2个不同的主视图使用。我只需要在使用其中一个特定主视图时设置这些属性,而不是其他视图。

所以,我想将设置默认值的操作放到那个特定的“主”视图中。似乎我不能在子视图中使用HiddenFor,然后在主视图中使用Html.Hidden。

有一种方法可以在子视图中检查外部视图吗?


如果默认值尚未设置,为何不在视图模型中设置默认值?这就是视图模型的作用。 - jgauffin
jgauffin:要求是“不更改后端代码”。 - Sunny Milenov
4个回答

74

如果我理解正确,你将会有类似这样的东西:

<input value="default" id="sth" name="sth" type="hidden">

要获取它,你需要写:

@Html.HiddenFor(m => m.sth, new { Value = "default" })

用于强类型视图。


7
Hidden相比,使用HiddenFor的一个缺点是输出中包括验证字符串(例如 data-val-required 和/或 data-val-number 属性)... 即使它是一个隐藏的字段。 - iCollect.it Ltd
16
似乎需要将“value”大写为“Value”。 - afreeland

40

除了HiddenFor,还有一个名为Hidden的辅助器可以让你设置值。

@Html.Hidden("RequiredProperty", "default")

编辑 根据您对问题所做的编辑,您可以这样做,但是我认为你正在进入领域,从长远来看,为争取代码更改会更便宜、更有效。正如您自己所说,控制器或视图模型应该设置默认值。

此代码:

<ul>
@{
        var stacks = new System.Diagnostics.StackTrace().GetFrames();
        foreach (var frame in stacks)
        {
            <li>@frame.GetMethod().Name - @frame.GetMethod().DeclaringType</li>
        }
}
</ul>

将会产生这样的输出:

Execute - ASP._Page_Views_ViewDirectoryX__SubView_cshtml
ExecutePageHierarchy - System.Web.WebPages.WebPageBase
ExecutePageHierarchy - System.Web.Mvc.WebViewPage
ExecutePageHierarchy - System.Web.WebPages.WebPageBase
RenderView - System.Web.Mvc.RazorView
Render - System.Web.Mvc.BuildManagerCompiledView
RenderPartialInternal - System.Web.Mvc.HtmlHelper
RenderPartial - System.Web.Mvc.Html.RenderPartialExtensions
Execute - ASP._Page_Views_ViewDirectoryY__MainView_cshtml

假设MVC框架总是经过相同的堆栈,那么您可以获取var frame = stacks[8];并使用声明类型确定您的父视图是谁,然后使用该确定来设置(或不设置)默认值。您还可以沿着堆栈向上遍历,而不是直接抓取[8],这样更安全但效率更低。


工作...但是我没有很好地解释真实情况。正在编辑问题,请审核。谢谢 - Sunny Milenov
@Sunny请注意修改,但请仅在紧急情况下使用此选项,以尽可能避免代码更改/部署。 - David Ruttka
哇,谢谢。我最终在@Html.Partial之后使用了jQuery来通过ID设置字段。很丑,但是有效 :) - Sunny Milenov
@Sunny 如果您要求您网站的所有用户启用JavaScript,那应该是可以的。如果您不要求用户这样做,您应该找到一种方法,即使在禁用JavaScript时,所有功能也能正常工作。 - David Ruttka
HiddenFor 相比,Hidden 的输出更轻量级。即使被隐藏且不会被使用,HiddenFor 仍可以在输出中包含多个验证字符串。 - iCollect.it Ltd

12
虽然我本来会选择Piotr的答案(因为它只有一行),但我惊讶地发现你的示例比你想象的更接近你的解决方案。从你现在拥有的东西来看,你只需要在使用Html辅助方法之前分配模型值即可。
@{Model.RequiredProperty = "default";}
@Html.HiddenFor(model => model.RequiredProperty)

0

这样怎么样?

public static MvcHtmlString HiddenFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object value, object htmlAttributes)
    {
        return HiddenFor(htmlHelper, expression, value, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
    }

    public static MvcHtmlString HiddenFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object value, IDictionary<string, object> htmlAttributes)
    {
        return htmlHelper.Hidden(ExpressionHelper.GetExpressionText(expression), value, htmlAttributes);
    }

使用方法如下

 @Html.HiddenFor(customerId => reviewModel.CustomerId, Site.LoggedInCustomerId, null)

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