Adding a image to database in ASP.NET MVC 5

asp.net-mvc c# entity-framework

Question

I'm trying to add an image to a database table using ASP.NET MVC with Entity Framework.

I've made a migration of existing ASP.NET MVC table named 'AspNetUsers' and added some new columns in it.

One of the columns is ProfilePicture, and it is byte[] type.

When I'm trying to register new user I'm expecting that user provide it's profile picture among other data.

Here is ApplicationUser class with newly added properties:

public class ApplicationUsers : IdentityUser
    {
        public string Name { get; set; }
        public string LastName { get; set; }
        public string City { get; set; }
        public string DateOfBirth { get; set; }
        public byte[] ProfilePicture { get; set; }

        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUsers> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        }
    }

To get the image into table I'm using class wrapper named ExtendedIdentityModels. This class inherits from RegisterViewModel class and it has only one property UserProfilePicture, type of HttpPostedFileBase, for getting the image from user's page.

 public class ExtendedIdentityModels : RegisterViewModel
    {
        public HttpPostedFileBase UserProfilePicture { get; set; }
    }

I've changed Register method in the controller to add this new properties to database:

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Register(ExtendedIdentityModels model)
    {
        if (ModelState.IsValid)
        {
            if (model.UserProfilePicture != null)
            {
                 if (model.UserProfilePicture.ContentLength > (4 * 1024 * 1024))
                 {
                      ModelState.AddModelError("CustomError", "Image can not be lager than 4MB.");
                            return View();
                 }
                 if (!(model.UserProfilePicture.ContentType == "image/jpeg" || model.UserProfilePicture.ContentType == "image/gif"))
                 {
                     ModelState.AddModelError("CustomError", "Image must be in jpeg or gif format.");
                 }
             }
             byte[] data = new byte[model.UserProfilePicture.ContentLength];
             model.UserProfilePicture.InputStream.Read(data, 0, model.UserProfilePicture.ContentLength);
             var user = new ApplicationUsers() { UserName = model.Email, Email = model.Email, Name = model.Name, LastName = model.LastName, City = model.City, DateOfBirth = model.DateOfBirth.ToString(), ProfilePicture = data };
             var result = await UserManager.CreateAsync(user, model.Password);
             if (result.Succeeded)
             {
                 await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);

                      return RedirectToAction("Index", "Home");
             }
                        AddErrors(result);

                }
                // If we got this far, something failed, redisplay form
                return View(model);
}

For interacting with user I use following View, on the bottom of this code is a part for adding ProfilePicture.

@model StudentBookApp.Models.ExtendedIdentityModels
@{
    ViewBag.Title = "Register";
}

@*<link rel="stylesheet" href="//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script>*@

<link href="~/Content/datepicker.css" rel="stylesheet" />
<script src="~/Scripts/bootstrap-datepicker.js"></script>
<h2>@ViewBag.Title.</h2>

@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()
    <h4>Create a new account.</h4>
    <hr />
    @Html.ValidationSummary("", new { @class = "text-danger" })

    <div class="form-group">
        @Html.LabelFor(m => m.Name, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.Name, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.LastName, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.LastName, new { @class = "form-control " })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.City, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.City, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.DateOfBirth, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.DateOfBirth, new { @class = "datepicker form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.PasswordFor(m => m.Password, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.ProfilePicture, new { @class = "col-md-2 control-label"})
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.UserProfilePicture, new {type = "file"})
            @Html.ValidationMessage("CustomMessage")
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" class="btn btn-default" value="Register" />
        </div>
    </div>
}

<script type="text/javascript">

    $(function () {
        $('.datepicker').datepicker();
    })
</script>

Almost everything goes well, but for model.UserProfilePicture I get null value. For some reason it doesn't get pass from View. What I'm doing wrong? I've been stuck for hours trying to find possible mistake, but no success. This kind of 'mechanism' for inserting image into table use to work well in MVC 4... Does someone sees what I'm missing and what's wrong in this kind of approach?

1
3
1/13/2015 1:39:34 PM

Accepted Answer

Nothing to do with MVC or c#, it's HTML ;) /edit Would also like to thank you for all the detail in the question since it was very thorough.

Your form needs enctype="multipart/form-data"

@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form", enctype="multipart/form-data" }))
4
1/13/2015 1:48:20 PM

Popular Answer

  public ActionResult AddImage(Brand model,HttpPostedFileBase image1)
        {
            var db = new H_Cloths_SaloonEntities();
            if (image1!=null)
            {

                model.Brandimage = new byte[image1.ContentLength];
                image1.InputStream.Read(model.Brandimage,0,image1.ContentLength);
            }
            db.Brands.Add(model);
            db.SaveChanges();
            ViewBag.Path = "image uploaded Successfully...!";
            return View(model);

        }


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow