web-dev-qa-db-fra.com

Comment définir une valeur cachée dans Razor

Je sais que ce que j'essaie de faire est une mauvaise idée, mais j'ai des contraintes spécifiques pour le moment.

J'ai plusieurs sites utilisant une seule et même base de code MVC3. Pour l'un d'eux, il est nécessaire de masquer certains champs obligatoires du formulaire.

Je sais que la meilleure approche consiste à modifier le contrôleur pour définir les valeurs par défaut de ces champs, mais j’aimerais atteindre cet objectif en modifiant uniquement la vue de ce site particulier sans modifier le code.

Alors, comment définir une propriété de modèle particulière sur une valeur par défaut dans la vue? L'idéal devrait être quelque chose comme:

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

EDIT: plus d'explication

En fait, il s’agit d’une sous-vue utilisée par deux vues principales différentes. Ces propriétés ne doivent être définies que si une vue principale est utilisée et non les autres.

Donc, je suppose que le réglage par défaut doit aller à cette vue "principale" particulière. On dirait que je ne peux pas utiliser HiddenFor dans la vue secondaire, puis Html.Hidden dans la vue principale.

Existe-t-il un moyen de vérifier dans la sous-vue qui est la vue extérieure?

32
Sunny Milenov

Il existe un assistant Hidden à côté de HiddenFor qui vous permet de définir la valeur. 

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

EDITSur la base de la modification que vous avez apportée à la question, vous pouvez le faire, mais je pense que vous vous dirigez vers un territoire où ce sera moins cher et plus efficace, à long terme, de se battre pour faire changer le code . Comme il a été dit, même par vous-même, le contrôleur ou le modèle de vue devrait définir les valeurs par défaut. 

Ce code:

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

Donnera une sortie comme ceci:

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

Donc, en supposant que l'infrastructure MVC passe toujours par la même pile, vous pouvez récupérer var frame = stacks[8]; et utiliser le type déclarant pour déterminer qui est votre vue parent, puis utiliser cette détermination pour définir (ou non) la valeur par défaut. Vous pouvez également parcourir la pile au lieu de saisir directement [8], ce qui serait plus sûr mais encore moins efficace.

31
David Ruttka

Si je comprends bien, vous aurez quelque chose comme ça:

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

Et pour l'obtenir, vous devez écrire:

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

pour une vue fortement typée.

67
Piotr Czyż

Alors que j'aurais choisi la réponse de Piotr (parce que tout est sur une ligne), j'ai été surpris de constater que votre échantillon est plus proche de votre solution que vous ne le pensez. À partir de ce que vous avez, vous affectez simplement la valeur du modèle avant d'utiliser la méthode d'assistance HTML.

@{Model.RequiredProperty = "default";}
@Html.HiddenFor(model => model.RequiredProperty)
10
alans

Que diriez-vous comme ça

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);
    }

Utilisez-le comme ça

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