passing parameters to my partial view?

前端 未结 4 1254
醉酒成梦
醉酒成梦 2020-12-29 19:55

I am calling my partial view like this:

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

Can I pass parameters to partial view?

4条回答
  •  -上瘾入骨i
    2020-12-29 20:15

    It took a while to sink in, but MVC means you use a Model, a View, and a Controller one way or another for just about everything, including Partial Views. How all three elements fit together can be a little intimidating at first. I'd never done one until just now, and it works --Woohoo!

    Hope this helps the next person.... Sorry, I'm using razor instead of .Net forms. I'm also pulling data from a SQL Server database into Entity Framework, which a developer is likely to use. I also probably went a little overboard with WebGrid, which is so much more elegant than a foreach statement. A basic @webgrid.GetHtml() will display every column and row.

    Background

    In this working example, users have uploaded pictures. Their pictures are displayed in their edit form using a partial view. The ImageID and FileName metadata is persisted in SQL Server while the file itself is persisted in the ~/Content/UserPictures directory.

    I know it's kinda half vast, because all the details of uploading and editing personal data isn't shown. Just the germane parts of using a Partial View are focused on, albeit with some bonus EF thrown in. The namespace is MVCApp3 for S&G.

    Partial View Model ViewModels.cs

    The SQL Server Images table includes many more columns in addition to ImageID and FileName such as [Caption], [Description], a MD5 hash to prevent the same image being uploaded multiple times, and upload date. The ViewModel distills the Entity down to the bare minimum needed for a user to see their pictures.

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

    Main View View Edit.cshtml

    Note the cast/convert to strongly type the ViewData[].

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

    If you don't set the strongly-typed model to use for the Partial View you'll get a "The model item passed into the dictionary is of type 'System.Data.Entity.DynamicProxies..." error because it assumes you're passing the parent/master model.

    Partial View View Picts.cshtml (the whole file contents is shown)

    @model IEnumerable
    @{
        var pictsgrid = new WebGrid(Model);
    }
        @pictsgrid.GetHtml(
            tableStyle: "grid",
            displayHeader: false,
            alternatingRowStyle: "alt",
            columns: pictsgrid.Columns( 
                pictsgrid.Column(format:@@item.ImageID
                @Html.ActionLink(linkText: "Delete", actionName: "DeletePicture", routeValues: new { id = @item.ImageID })
                )
                ))
    

    Controller IdentityController.cs

    Set the data content into the ViewData["MyPartialViewModelKeyName"] your partial view will consume. You can give the dictionary key any name you want, but I gave it ViewData["Picts"] to be consistent with the partial view file name and its view model class definition.

    Because the pictures may be shared amongst multiple users there is a many-to-many table with a corresponding PITA query in Entity Framework using nested froms and inner joins to return just the pictures belonging to, or shared with, a user:

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

提交回复
热议问题