Rectangle 27 6

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.

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.

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

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

@Html.Partial(
      partialViewName: "Picts", 
      model: (IEnumerable<MVCApp3.Models.Picts>)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<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>)
            ))

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

You rock so much awesomeness. You just spelled all that out in a way that really clicked and saved me from missing my deadline. I <3 you for taking the time to do all that! Thank you!!!

asp.net mvc - passing parameters to my partial view? - Stack Overflow

asp.net-mvc renderpartial
Rectangle 27 6

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.

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.

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

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

@Html.Partial(
      partialViewName: "Picts", 
      model: (IEnumerable<MVCApp3.Models.Picts>)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<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>)
            ))

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

You rock so much awesomeness. You just spelled all that out in a way that really clicked and saved me from missing my deadline. I <3 you for taking the time to do all that! Thank you!!!

asp.net mvc - passing parameters to my partial view? - Stack Overflow

asp.net-mvc renderpartial