passer des paramètres à ma vue partielle?

J'appelle ma vue partielle comme ceci:

 <% Html.RenderPartial("~/controls/users.ascx"); %>

Puis-je passer des paramètres à la vue partielle? Comment vais-je y accéder dans les utilisateurs réels.ascx page?

33
demandé sur mrblah 2009-12-15 20:43:33

4 réponses

Vous pouvez passer un objet modèle au partiel (par exemple une liste de chaînes):

<% Html.RenderPartial("~/controls/users.ascx", new string[] { "foo", "bar" }); %>

Ensuite, vous tapez fortement le partiel et la propriété Model sera du type approprié:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.Collections.Generic.IEnumerable<string>>" %>

<% foreach (var item in Model) { %>
    <div><%= Html.Encode(item) %></div>
<% } %>
31
répondu Darin Dimitrov 2009-12-15 17:49:39

Il y a une autre surcharge pour RenderPartial qui passera votre modèle à travers.

<% Html.RenderPartial("~/controls/users.ascx", modelGoesHere); %>

Comment accéder? Tout comme vous le feriez normalement avec n'importe quelle vue:

<%= Model.MagicSauce %>
17
répondu jfar 2009-12-15 17:48:17

Il a fallu un certain temps pour s'infiltrer, mais MVC signifie que vous utilisez un modèle, une vue et un contrôleur d'une manière ou d'une autre pour à peu près tout, y compris les vues partielles. La façon dont les trois éléments s'emboîtent peut être un peu intimidante au début. Je n'en avais jamais fait jusqu'à maintenant ,et ça marche ... Woohoo!

J'espère que cela aidera la prochaine personne.... Désolé, j'utilise razor au lieu de formulaires.Net. Je tire également des données d'une base de données SQL Server dans Entity Framework, qu'un développeur est susceptible d'utiliser. Je aussi est probablement allé un peu trop loin avec WebGrid, qui est tellement plus élégant qu'une déclaration foreach. Un @webgrid de base.GetHtml() affichera chaque colonne et ligne.

Contexte

Dans cet exemple de travail, les utilisateurs ont téléchargé des images. Leurs images sont affichées dans leur formulaire d'édition en utilisant une vue partielle. Les métadonnées ImageID et FileName sont conservées dans SQL Server tandis que le fichier lui-même est conservé dans le répertoire ~/Content/UserPictures.

Je sais que c'est un peu la moitié vaste, parce que tous les détails du téléchargement et de l'édition des données personnelles ne sont pas affichés. Seules les parties pertinentes de l'utilisation d'une vue partielle sont axées sur, mais avec un peu de bonus EF jeté. L'espace de noms est MVCApp3 pour S & G.

Modèle De Vue Partielle ViewModels.cs

La table D'Images SQL Server comprend beaucoup plus de colonnes en plus de ImageID et FileName telles que [Caption], [Description], un hachage MD5 pour empêcher la même image d'être téléchargée plusieurs fois, et upload date. Le ViewModel distille l'entité au strict minimum nécessaire pour qu'un utilisateur puisse voir ses images.

public class Picts
{
    public int ImageID { get; set; }
    public string FileName { get; set; }
}

Vue Principale Vue Modifier.cshtml

Notez le cast / convert pour taper fortement ViewData [].

 @Html.Partial(
      partialViewName: "Picts", 
      model: (IEnumerable<MVCApp3.Models.Picts>)ViewData["Picts"]
 )

Si vous ne définissez pas le modèle fortement typé à utiliser pour la vue partielle, vous obtiendrez un "L'élément de modèle passé dans le dictionnaire est de type ' System.Données.Entité.DynamicProxies..." erreur car elle suppose que vous passez le parent / maître modèle.

Vue Partielle De La Vue Pictes.cshtml (tout le contenu du fichier est affiché)

@model IEnumerable<MVCApp3.Models.Picts>
@{
    var pictsgrid = new WebGrid(Model);
}
    @pictsgrid.GetHtml(
        tableStyle: "grid",
        displayHeader: false,
        alternatingRowStyle: "alt",
        columns: pictsgrid.Columns( 
            pictsgrid.Column(format:@<text><img src="@Url.Content("~/Content/Users/" + @item.FileName)" alt="@item.ImageID" width="200" />
            @Html.ActionLink(linkText: "Delete", actionName: "DeletePicture", routeValues: new { id = @item.ImageID })
            </text>)
            ))

Contrôleur IdentityController.cs

Définissez le contenu des données dans ViewData ["MyPartialViewModelKeyName"] votre vue partielle consommera. Vous pouvez donner à la clé du dictionnaire le nom que vous voulez, mais je lui ai donné ViewData["Picts"] pour être cohérent avec le nom du fichier de vue partielle et sa définition de classe de modèle de vue.

Parce que les images peuvent être partagées entre plusieurs utilisateurs il existe une table plusieurs à plusieurs avec une requête pita correspondante dans Entity Framework utilisant des froms imbriqués et des jointures internes pour renvoyer uniquement les images appartenant à un utilisateur ou partagées avec lui:

public class IdentityController : Controller
{
    private EzPL8Entities db = new EzPL8Entities();

    // GET: /Identity/Edit/5
    [Authorize]
    public ActionResult Edit(int? id)
    {

        if (id == null)
            return new HttpNotFoundResult("This doesn't exist");

      // get main form data
      ezpl8_UsersPhysicalIdentity ezIDobj = db.ezpl8_UsersPhysicalIdentity.Find(id)

    // http://learnentityframework.com/LearnEntityFramework/tutorials/many-to-many-relationships-in-the-entity-data-model/
    // get partial form data for just this user's pictures
                ViewData["Picts"] = (from user in db.ezpl8_Users
                             from ui in user.ezpl8_Images
                             join image in db.ezpl8_Images
                             on ui.ImageID equals image.ImageID
                             where user.ezpl8_UserID == id
                             select new Picts
                             {
                                 FileName = image.FileName,
                                 ImageID = image.ImageID
                             }
                                 ).ToList();

        return View(ezIDobj);
    }

   //  Here's the Partial View Controller --not much to it!
    public ViewResult Picts(int id)
    {
       return View(ViewData["Picts"]);
    }

    [Authorize]  //you have to at least be logged on
    public ActionResult DeletePicture(int id)
    {
        //ToDo:  better security so a user can't delete another user's picture 
        //    TempData["ezpl8_UserID"]
        ezpl8_Images i = db.ezpl8_Images.Find(id);
        if (i != null)
        {
            var path = System.IO.Path.Combine(Server.MapPath("~/Content/Users"), i.FileName);
            System.IO.File.Delete(path: path);

            db.ezpl8_Images.Remove(i);
            db.SaveChanges();
        }
        return Redirect(Request.UrlReferrer.ToString());
    }

    protected override void Dispose(bool disposing)
    {
        db.Dispose();
        base.Dispose(disposing);
    }
}
6
répondu Jules Bartow 2012-06-12 19:04:29
// get main form data
ezpl8_UsersPhysicalIdentity ezIDobj = db.ezpl8_UsersPhysicalIdentity.Find(id)

// http://learnentityframework.com/LearnEntityFramework/tutorials/many-to-many-relationships-in-the-entity-data-model/
// get partial form data for just this user's pictures
            ViewData["Picts"] = (from user in db.ezpl8_Users
                         from ui in user.ezpl8_Images
                         join image in db.ezpl8_Images
                         on ui.ImageID equals image.ImageID
                         where user.ezpl8_UserID == id
                         select new Picts
                         {
                             FileName = image.FileName,
                             ImageID = image.ImageID
                         }
                             ).ToList();

    return View(ezIDobj);
}

/ / Voici le contrôleur de vue partielle-pas grand-chose! public ViewResult Pictes(int id) { retour Vue (ViewData ["Picts"]); }

[Authorize]  //you have to at least be logged on
public ActionResult DeletePicture(int id)
{
    //ToDo:  better security so a user can't delete another user's picture 
    //    TempData["ezpl8_UserID"]
    ezpl8_Images i = db.ezpl8_Images.Find(id);
    if (i != null)
    {
        var path = System.IO.Path.Combine(Server.MapPath("~/Content/Users"), i.FileName);
        System.IO.File.Delete(path: path);

        db.ezpl8_Images.Remove(i);
        db.SaveChanges();
    }
    return Redirect(Request.UrlReferrer.ToString());
}

protected override void Dispose(bool disposing)
{
    db.Dispose();
    base.Dispose(disposing);
}

}

0
répondu user2689416 2013-08-16 12:53:02