web-dev-qa-db-fra.com

MVC Razor - Meilleures pratiques de création/édition de vues

Je travaille avec MVC 3/Razor pour la première fois et il semble étrange que tous les exemples et les échafaudages VS pour la création et la modification de vues aient tous des vues HTML distinctes pour ces concepts.

Il n'y a vraiment pas beaucoup de différence entre de nombreux formulaires Créer/Modifier, alors je me demandais pourquoi je ne trouvais pas d'exemples de personnes utilisant un seul formulaire de mise à jour pouvant être utilisées à la fois par les actions Créer et Modifier.

J'ai réussi à faire fonctionner une vue Update.cshtml mais je me demandais comment il communiquait avec la méthode d'action Edit ou Create du contrôleur.

Mes questions sont:

  1. Quelqu'un a une réponse rapide à parler au contrôleur, ou
  2. Quelqu'un connaît-il un tutoriel illustrant les bonnes pratiques pour travailler de cette manière, ou
  3. Existe-t-il une bonne raison de garder les vues Créer/Modifier séparées lorsque le code HTML est souvent identique.

A bientôt Dave

21
David Cruwys

Ce (genre!) Question est posée avant: ASP.NET MVC - en utilisant le même formulaire pour créer et éditer

En gros, vous pouvez créer une vue partielle et l’inclure dans les vues Créer et Modifier. 

Scott Guthrie a publié un article intéressant sur Vues partielles .

(J'ai lu quelque chose à ce sujet quelque part, mais je ne le trouve pas, je mettrai ce message à jour lorsque je le trouverai)

10
Rhapsody

Sachez que les réponses à votre question doivent également être dictées par les besoins de l'entreprise (et les rôles). L'échafaudage fournit des fonctionnalités distinctes, ce qui est dans certains cas l'implémentation préférée.

Les fonctionnalités CREATE et EDIT sont souvent pratiquement identiques d’un point de vue technique (programmation). Cela peut amener une personne technique à penser que la fonctionnalité doit être combinée afin de mettre en œuvre une solution technique plus efficace. Toutefois, toute mise en œuvre technique doit répondre aux besoins de l’entreprise, ce qui peut nécessiter une séparation (par exemple, en fonction du rôle de l’entreprise) de ces préoccupations.

Par exemple, une entreprise peut exiger que le rôle pour lequel les objets métier CREATEs ne soient pas identique à celui qu'ils modifient. Dans ce cas, les pages Web implémentées peuvent ne pas être vues par les mêmes rôles (et les mêmes personnes).

Si vous implémentez CREATE et EDIT à l'aide de fonctionnalités communes, mais que le besoin commercial concerne la séparation des rôles, vous devez toujours implémenter la "vérification de rôle" avant de rendre la vue/vue partielle/etc. Dans de tels cas, des vues séparées peuvent constituer une implémentation préférée.

8
pixelda

Je fais ça. Je ne sais pas si c'est la meilleure pratique mais ça peut être Nice. Il existe certaines situations dans lesquelles une vue d'ajout/modification complètement distincte peut être utile. En outre, si vous utilisez ViewModels, autant que je sache, vous êtes coincé (e) en utilisant le même ViewModel pour les ajouts et les modifications. En théorie, ils devraient tous les deux avoir leur propre ViewModels. 

Voici à quoi cela ressemble pour moi:

AddVideo.cshtml

@model Multimedia.MediaVideoViewModel

@{
    Layout = "~/Views/Shared/LiveSubLayout.cshtml";
}

@section AdditionalHeadContent {

}

<div class="page-header">
    <h1>Add a new video</h1>
</div>

<div id="add-video" class="row-fluid">
    @Html.Partial("_VideoForm", Model, new ViewDataDictionary { { "ActionKeyword", "Add" } })
</div>

EditVideo.cshtml

@model Multimedia.MediaVideoViewModel

@{
    Layout = "~/Views/Shared/LiveSubLayout.cshtml";
}

@section AdditionalHeadContent {

}

@if (ViewBag.Success)
{
    <div class="alert alert-success">
    <button class="close" data-dismiss="alert">×</button>
        <h3><strong>Video saved!</strong></h3><br/>
        <div class="btn-group">
          <a href="#" class="btn">Preview this video</a>
          @Html.ActionLink("Add Another Video", "AddVideo", "Multimedia", new { Model.Id }, new { @class = "btn" })
          @Html.ActionLink("View all media", "Index", "Multimedia", null, new { @class = "btn" })
        </div>
        <p>or continue editing below...</p>
    </div>
}

<div class="page-header">
    <h1>Edit video <small>@Model.Title</small></h1>
</div>

<div id="edit-video" class="row-fluid">
    @Html.Partial("_VideoForm", Model, new ViewDataDictionary { { "ActionKeyword", "Edit" } })
</div>

_VideoForm.cshtml (partiel)

@model Multimedia.MediaVideoViewModel

@{
    string actionKeyword = ViewData["ActionKeyword"].ToString();
}

<div class="span6">

    @using (Html.BeginForm("editvideo", "multimedia"))
    {
        <label class="control-label" id="embed-url">Paste video URL here:</label>
        <div class="control-group">
            @Html.TextBoxFor(model => model.EmbedUrl, new { @class = "span12", id = "video-url", placeholder = "ex: http://www.youtube.com/watch?v=PoAGasPLh30" })
            <button class="btn disabled" id="get-video" title="Tooltip">Get Video</button>
        </div>

        <div class="video-meta">

            <h3>Video Information</h3>
            <label class="control-label">Title:</label>

            <div class="control-group">
                @Html.TextBoxFor(model => model.Title, new { @class = "span12", id = "video-title" })
                @Html.ValidationMessageFor(model => model.Title, "A title is required", new { @class = "label label-important" })
            </div>

            <label class="control-label">Description:</label>
            <div class="control-group">
                @Html.TextAreaFor(model => model.Description, new { @class = "span12", id = "video-description" })
            </div>

            <h3>Categories</h3>

            <div id="tag-search" class="well">
                    <label class="control-label">Search tags:</label>
                    <div class="controls"><input type="text" class="typeahead" /></div>
                    @if (Model != null)
                    {
                        foreach (var category in Model.Tags)
                        {
                            @Html.Partial("_TagFragment", category)
                        }
                    }
            </div>

            <hr />

            @Html.HiddenFor(model => model.Id)
            @Html.HiddenFor(model => model.ThumbnailUrl, new { id = "thumb-url" })
            <input type="submit" id="video-submit" name="video-submit" class="btn-large btn-primary" value="@actionKeyword video" />
        </div>
    }

</div>

J'ai édité ces versions un peu, donc il manque peut-être quelque chose, mais cela devrait vous donner une idée générale.

3
Ryan Bosinger

voici comment je le fais, ce n'est pas toujours la meilleure pratique (cela dépend du cas)

1/combiner les actions du contrôleur pour créer et éditer

public PartialViewResult Creedit(string id = null)
{
    if (id == null)
    {
        // Create new record (this is the view in Create mode)
        return PartialView();
    }
    else
    {
        // Edit record (view in Edit mode)
        Client x = db.ClientSet.Find(id);
        if (x == null) { return PartialView("_error"); }
        // ...
        return PartialView(x);
    }
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Creedit(Client x)
{
    if (x.id == null)
    {
        // insert new record
    }
    else
    {
        // update record
    }
}

2/combinez l'édition et créez des vues dans une vue que j'ai appelée Creedit

// if you need to display something unique to a create view
// just check if the Model is null
@if(Model==null){
}

j'ai donc 1 vue et 2 actions (1 post et 1 get) au lieu de 2 vues et 4 actions.

0
Chtiwi Malek