Reputation: 687
I'm trying to build the functionality where the user can upload a profile image to blob storage on registration and then i can be called and included in the manage index view.
I have been able to create the container but no blob is showing inside the container and the url is not being saved to the database either (just NULL) so I'm feeling like its the controller code that's the issue.
CONTROLLER
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model,
HttpPostedFileBase photo, PhotoService photoService)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.Email, Email = model.Email, PhotoUrl = model.PhotoUrl };
ApplicationUser.PhotoUrl = await photoService.UploadPhotoAsync(photo);
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
// For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=320771
// Send an email with this link
// string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
// var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
// await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>");
//var db = new ApplicationDbContext();
//model.PhotoUrl = await photoService.UploadPhotoAsync(photo);
//db.Users.Add(user);
//db.SaveChanges();
return RedirectToAction("Index", "Home");
}
AddErrors(result);
}
// If we got this far, something failed, redisplay form
return View(model);
}
MODEL
public class RegisterViewModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
public string PhotoUrl { get; set; }
}
SERVICE
public class PhotoService : IPhotoService
{
async public Task<string> UploadPhotoAsync(HttpPostedFileBase photoToUpload)
{
if (photoToUpload == null || photoToUpload.ContentLength == 0)
{
return null;
}
string fullPath = null;
Stopwatch timespan = Stopwatch.StartNew();
try
{
CloudStorageAccount storageAccount = StorageUtils.StorageAccount;
// Create the blob client and reference the container
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("images");
// Create a unique name for the images we are about to upload
string imageName = String.Format("task-photo-{0}{1}",
Guid.NewGuid().ToString(),
Path.GetExtension(photoToUpload.FileName));
// Upload image to Blob Storage
CloudBlockBlob blockBlob = container.GetBlockBlobReference(imageName);
blockBlob.Properties.ContentType = photoToUpload.ContentType;
await blockBlob.UploadFromStreamAsync(photoToUpload.InputStream);
fullPath = blockBlob.Uri.ToString();
timespan.Stop();
// log.TraceApi("Blob Service", "PhotoService.UploadPhoto", timespan.Elapsed, "imagepath={0}", fullPath);
}
catch (Exception ex)
{
// log.Error(ex, "Error upload photo blob to storage");
throw;
}
return fullPath;
}
I'm working on this with this tutorial as a guide - https://learn.microsoft.com/en-us/aspnet/aspnet/overview/developing-apps-with-windows-azure/building-real-world-cloud-apps-with-windows-azure/unstructured-blob-storage
Would really appreciate it if someone could let me know how to get this working.
Thanks
Upvotes: 0
Views: 594
Reputation: 18465
"an object reference is required for the nonstatic field method or property".
You need to init your user
as follows:
var user = new ApplicationUser {
UserName = model.Email,
Email = model.Email,
PhotoUrl = await photoService.UploadPhotoAsync(photo)
};
var result = await UserManager.CreateAsync(user, model.Password);
Moreover, I found the tutorial defined a interface IPhotoService
and implement it by the PhotoService
class, but I found you define the PhotoService
in your Register
action. In order to leverage dependency injection, I would recommend you follow this tutorial.
Also, I would recommend you move the HttpPostedFileBase photo
parameter from the Register
method into your RegisterViewModel
as follows:
public class RegisterViewModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
public HttpPostedFileBase Photo { get; set; }
}
Then, you could init your ApplicationUser
instance as follows:
var user = new ApplicationUser {
UserName = model.Email,
Email = model.Email,
PhotoUrl = await photoService.UploadPhotoAsync(model.Photo)
};
And for your register view, you could init the input file as follows:
@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form", enctype = "multipart/form-data" }))
{
//other properties
@Html.TextBoxFor(m => m.Photo, new {type = "file"})
}
TEST:
In general, you need to make sure you have set the multipart/form-data
for your register form in the register view. And the parameter photoService
in the Register
method is not null. Also, you need to make sure your container name images
exists, or you need to await container.CreateIfNotExistsAsync()
. Additionally, you could leverage debugging via Visual Studio and step into your code to narrow this issue, details about how to debug, you could follow here.
Upvotes: 1