how to handle Edit Post on multiple images Asp.Net MVC - asp.net-mvc

hi every one first time to ask here. So here is my Create post method on multiple images plus other data entries and it works with out any problem and it uploads all images and the content. My question is how to handle edit Post controller on multiple images.
here is the Create controller
public ActionResult SaveDataAdded([Bind(Include = "SId,Category,SName,LocalName,CommonName,Description,PicTakenBy,ContentBy,EditedBy")]SpeciesDataTable ARow, HttpPostedFileBase file,HttpPostedFileBase file2, HttpPostedFileBase file3, HttpPostedFileBase file4)
{if (ModelState.IsValid)
{
if (file != null && file.ContentLength > 0)
{
using (var Bnryreader = new System.IO.BinaryReader(file.InputStream))
{
ARow.MainPic = Bnryreader.ReadBytes(file.ContentLength);
}
}
if (file2 != null && file2.ContentLength > 0)
{
using (var reader = new System.IO.BinaryReader(file2.InputStream))
{
ARow.SecPic = reader.ReadBytes(file2.ContentLength);
}
}
if (file3 != null && file3.ContentLength > 0)
{
using (var reader = new System.IO.BinaryReader(file3.InputStream))
{
ARow.ThirdPic = reader.ReadBytes(file3.ContentLength);
}
}
if (file4 != null && file4.ContentLength > 0)
{
using (var reader = new System.IO.BinaryReader(file4.InputStream))
{
ARow.FourthPic = reader.ReadBytes(file4.ContentLength);
}
}
db.SpeciesDataTables.Add(ARow);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(ARow);
}
and here is the code block for edit. Probably my approach was not correct. But i need help on this.
public ActionResult EditSpeciesPost([Bind(Include = "SId,Category,SName,LocalName,CommonName,Description,PicTakenBy,ContentBy,EditedBy")]SpeciesDataTable Editor, HttpPostedFileBase file, HttpPostedFileBase file2, HttpPostedFileBase file3, HttpPostedFileBase file4)
{
if (file != null && file.ContentLength > 0)
{
using (var reader = new System.IO.BinaryReader(file.InputStream))
{
Editor.MainPic = reader.ReadBytes(file.ContentLength);
}
}
if (file2 != null && file2.ContentLength > 0)
{
using (var reader = new System.IO.BinaryReader(file2.InputStream))
{
Editor.SecPic = reader.ReadBytes(file2.ContentLength);
}
}
if (file3 != null && file3.ContentLength > 0)
{
using (var reader = new System.IO.BinaryReader(file3.InputStream))
{
Editor.ThirdPic = reader.ReadBytes(file3.ContentLength);
}
}
if (file4 != null && file4.ContentLength > 0)
{
using (var reader = new System.IO.BinaryReader(file4.InputStream))
{
Editor.FourthPic = reader.ReadBytes(file4.ContentLength);
}
}
db.Entry(Editor).State = EntityState.Modified;
db.SaveChanges();
//return RedirectToAction("Index");
return View(Editor);
}
here is the view for edit
#using(Html.BeginForm("EditSpecies", "Species", null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="col-md-10">
#if (Model.MainPic != null) // to view first image
{
var base64 = Convert.ToBase64String(Model.MainPic);
var imgsrc = string.Format("data:image/jpg;base64,{0}", base64);
<img src='#imgsrc' style="max-width:100px;max-height:100px" />
}
</div>
<div class="col-md-10">
<input type="file" name="file" /> // input for first image
</div>
<div class="col-md-10">
#if (Model.SecPic != null)// to view second image
{
var base64 = Convert.ToBase64String(Model.SecPic);
var imgsrc = string.Format("data:image/jpg;base64,{0}", base64);
<img src='#imgsrc' style="max-width:50px;max-height:50px" />
}
</div>
<div class="col-md-10">
<input type="file" name="file2" /> input for third image
</div>
// and it continues to third and fourth picture
}

What you should be doing is, sending only null for the images user has not updated in the UI and post the data to the httppost action method where you read the existing entity and update only those properties needed to update.
I would create a view model for my view with properties needed for the view.
public class SpeciesVm
{
public int Id { set; get; }
public string Name { set; get; }
public string LocalName { set; get; }
public HttpPostedFileBase MainImg { set; get; }
public HttpPostedFileBase SecondImg { set; get; }
public string MainPicImgSrc { set; get; }
public string SecondPicImgSrc { set; get; }
}
Now in your GET action, you create an object of this, load the property values.
public ActionResult Edit(int id)
{
var e=db.SpeciesDataTables.Find(id);
var vm = new SpeciesVm() { Id=id , Name =e.SName };
vm.LocalName= e.LocalName;
if(e.MainPic!=null)
{
vm.MainPicImgSrc = $"data:image/jpg;base64,{Convert.ToBase64String(e.MainPic)}";
}
if(e.SecPic!=null)
{
vm.SecondPicImgSrc = $"data:image/jpg;base64,{Convert.ToBase64String(e.SecPic)}";
}
return View(vm);
}
Now in your view, you will use the properties of type HttpPostedFileBase for the file input
#model SpeciesVm
#using (Html.BeginForm("Edit","Species", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
#Html.HiddenFor(a=>a.Id)
#Html.HiddenFor(a=>a.Name)
#Html.HiddenFor(a=>a.LocalName)
<div class="col-md-10">
#if (!string.IsNullOrEmpty(Model.MainPicImgSrc))
{
<img src='#Model.MainPicImgSrc' />
}
<input type="file" name="MainImg" />
</div>
<div class="col-md-10">
#if (!string.IsNullOrEmpty(Model.SecondPicImgSrc))
{
<img src='#Model.SecondPicImgSrc' />
}
<input type="file" name="SecondImg" />
</div>
<button type="submit">Save</button>
}
Now in your HttpPost action method, you will use the same view model as the parameter, read the Id property value, using which read existing entity and update the properties as needed.
[HttpPost]
public ActionResult Edit(SpeciesVm model)
{
var e=db.SpeciesDataTables.Find(id);
e.SName = model.Name;
//Update the image properties only if it was send from the form
if(model.MainImg!=null)
{
e.MainPic = GetByteArrayFromImage(model.MainImg);
}
if(model.MainImg!=null)
{
e.SecPic = GetByteArrayFromImage(model.SecondImg);
}
db.SaveChanges();
return RedirectToAction("Index");
}
private byte[] GetByteArrayFromImage(HttpPostedFileBase file)
{
if (file == null)
return null;
var target = new MemoryStream();
file.InputStream.CopyTo(target);
return target.ToArray();
}

Related

MVC Binding to a transformed property

I have an object class Tag {string Key; string Text;} and an object Record that is bind to a storage table.
class Record { [...Id & other properties...]
public string Name { get; set; } // "FirstRecord"
public string Tags { get; set; } // "3,4,9"
}
Updating the Name does not present a problem. But I have some difficulties with the Tags... As you can see the Tags property is the CSV of int keys (say {1:".net",2:"java",3:"perl" ...}).
In the Record's Edit View I build a dictionary with all available Tags:
Dictionary<string, string> tags = ViewData["tags"] as Dictionary<string, string>;
[...]
<div class="form-group">
<label class="col-md-2 control-label">Tags</label>
<div class="col-md-10">
#foreach (var tag in tags)
{
<div class="checkbox-inline">
<label for="tag_#tag.Key">
<input type="checkbox" id="tag_#tag.Key" value="#tag.Key" />
#tag.Value
</label>
</div>
}
</div>
</div>
And finally I have the Edit Post controller, like this
// POST: Records/Edit/5
[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(string id, [Bind("Id,Name")] Record record)
{
if (id != record.Id) {
return NotFound();
}
if (ModelState.IsValid) {
try {
await repository.UpdateTableEntityAsync(record);
}
catch (Exception) { [...] }
return RedirectToAction("Index");
}
return View(record);
}
So, I am confused if I should Bind Tags, like [Bind("Id,Name,Tags")], because that value should be taken from all the checked check-boxes values, then concatenated as CSV to be ready to be updated in the storage...
If you want to bind the checkbox values to a string, you could get all the values of checkbox and set the value of model manually. Code below is for your reference.
In view, add a name property for checkbox.
<input type="checkbox" name="tag_#tag.Key" id="tag_#tag.Key" value="#tag.Key" />
In action, we could get all the values of checkbox using Request.Form.
[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(string id, [Bind("Id,Name")] Record record)
{
if (id != record.Id)
{
return NotFound();
}
record.Tags = "";
foreach (var key in Request.Form.AllKeys)
{
if (key.StartsWith("tag_"))
{
record.Tags += Request.Form[key] + ",";
}
}
if (record.Tags.Length > 0)
{
record.Tags = record.Tags.Remove(record.Tags.Length - 1, 1);
}
if (ModelState.IsValid)
{
try
{
await repository.UpdateTableEntityAsync(record);
}
catch (Exception)
{
}
return RedirectToAction("Index");
}
return View(record);
}

Uploading images from different input files in MVC

I want to upload Images to a database. The database contains url images and images uploads to folder in file system. I have the following tables in the database,
Furniture
MainFileDetails (1-1 relationship with Furniture) where store the main image
FileDetails (1-Many relationship with Furniture) where we store other images associated with Furniture.
Here is my code:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Furniture furniture , HttpPostedFileBase fileTwo, HttpPostedFileBase file)
{
if (ModelState.IsValid)
{
for (int i = 0; i < Request.Files.Count; i++)
{
fileTwo = Request.Files[i];
if (fileTwo != null && fileTwo.ContentLength > 0)
{
var fileNameTwo = Path.GetFileName(fileTwo.FileName);
MainFileDetails mainFileDetail = new MainFileDetails()
{
FileName = fileNameTwo,
Extension = Path.GetExtension(fileNameTwo),
Id = Guid.NewGuid(),
FurnitureId = furniture.FurnitureId
};
var pathMain = Path.Combine(Server.MapPath("~/Upload/MainPage/"), mainFileDetail.Id + mainFileDetail.Extension);
fileTwo.SaveAs(pathMain);
db.Entry(mainFileDetail).State = EntityState.Modified;
db.SaveChanges();
FileDetail fileDetail = new FileDetail()
{
NameFile = fileNameTwo, //or mainFileDetail.FileName
Extension = Path.GetExtension(fileNameTwo), //or mainFileDetail.Extension
Id = Guid.NewGuid(),
FurnitureId = furniture.FurnitureId //or mainFileDetail. FurnitureId
};
var path = Path.Combine(Server.MapPath("~/Upload/"), fileDetail.Id + fileDetail.Extension);
file.SaveAs(path);
db.Entry(fileDetail).State = EntityState.Added;
}
}
db.Entry(furniture).State = EntityState.Modified;
db.SaveChanges();
TempData["message"] = string.Format("Changes in \"{0}\" has been saved", furniture.Name);
return RedirectToAction("Index");
}
ViewBag.CategoryId = new SelectList(db.Categories, "CategoryId", "Name", furniture.CategoryId);
return View(furniture);
}
My View:
#model FurnitureStore.Entities.Furniture
....
#using (Html.BeginForm("Edit", "Furnitures", FormMethod.Post, new { enctype = "multipart/form-data"}))
{
....
#Html.HiddenFor(model => model.FurnitureId)
#Html.LabelFor(model => model.Name)
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
.... // more inputs for properties of the model
#Html.LabelFor(model => model.CategoryId, "Category")
#Html.DropDownList("CategoryId", null)
#Html.ValidationMessageFor(model => model.CategoryId, "", new { #class =
// Main file
<input type="file" name="fileTwo" />
#if(Model.MainFileDetails.Id == null)
{
<div class="form-control-static">No image</div>
}
else
{
<img src="~/Upload/MainPage/#(Model.MainFileDetails.Id + Model.MainFileDetails.Extension)" width="240" height="240" />
}
// Other files
<input type="file" name="file" multiple="multiple" />
<ul class="attachment">
#foreach (var item in Model.FileDetails)
{
<li style="list-style-type:none; display:inline;">
<img src="~/Upload/#(item.Id + item.Extension)" />
X
</li>
}
</ul>
<input type="submit" value="Save" class="btn btn-primary" />
}
But I have a problem. All photo just uploads to the Upload/MainPage folder. I want to upload photo separately to MainPage in one table and separately to gallery (other table).
How can I fix my code, because last uploaded photo in gallery table replaces photo in MainPage?
The foreach loop in your controller method is looping through every file you have uploaded, and then you create a new MainFileDetails for each file and save it. You need to get the 'main file' from the first file input and save it to MainFileDetails and then loop through the files in the second file input and save each of them to FileDetails.
To solve the immediate problem, change your method to
public ActionResult Edit(Furniture furniture , HttpPostedFileBase fileTwo, IEnumerable<HttpPostedFileBase> file)
and those parameters will be bound with the values for the file inputs. Then its simply
if (ModelState.IsValid)
{
if (fileTwo != null && fileTwo.ContentLength > 0)
{
// create an instance of MainFileDetails and set its properties based on
// the values of fileTwo and save
}
foreach (HttpPostedFileBase image in file)
{
// create an instance of FileDetails and set its details based on
// the values of image and save
}
db.Entry(furniture).State = EntityState.Modified;
db.SaveChanges();
....
There are however numerous other potential issues with your code.
Rule 1. Your editing data, so always use a view model. What is
ViewModel in
MVC?
Its unclear why you need a separate 1 to 1 table for the main image.
The properties for that could be stored in the Furniture table.
Alteratively you could just have the 1 to Many table, and have a
bool IsMainImage property which would allow you to easily swap
which is the main image.
You images table (FurnitureImages would be a more appropriate name)
should include a auto-incremented int ID for the PK and properties
for the file path and file display name
If ModelState is invalid, you return the view, but all the files
are lost and the poor user needs to re-select them all again
Your view models should be
public class FurnitureVM
{
public int? ID { get; set; }
[Required( ... )]
public string Name { get; set; }
.... // other properties of Furniture that you need in the view
[Required( ... )]
public int? Category { get; set; }
public IEnumerable<SelectListItem> CategoryList { get; set; }
public HttpPostedFileBase MainFile { get; set; }
public IEnumerable<HttpPostedFileBase> SecondaryFiles { get; set; }
public ImageVM MainImage { get; set; }
public List<ImageVM> SecondaryImages { get; set; }
}
public class ImageVM
{
public int? ID { get; set; }
public string Path { get; set; }
public string DisplayName { get; set; }
}
And the view
#model yourAssembly.FurnitureVM
....
#using (Html.BeginForm("Edit", "Furnitures", FormMethod.Post, new { enctype = "multipart/form-data"}))
{
// Note: no need for a hidden input for the ID property assuming your using the default routing
#Html.LabelFor(m => m.Name)
#Html.EditorFor(m => m.Name)
#Html.ValidationMessageFor(m => m.Name)
.... // more inputs for properties of the model
#Html.LabelFor(m => m.Category)
#Html.DropDownListFor(m => m.Category, Model.CategoryList, "Please select")
#Html.ValidationMessageFor(m => m.Category)
// Main file
#Html.TextBoxFor(m => m.MainFile, new { type = "file" })
#Html.ValidationMessageFor(m => m.MainFile)
if (Model.MainImage != null)
{
#Html.HiddenFor(m => m.MainImage.ID)
#Html.HiddenFor(m => m.MainImage.Path)
#Html.HiddenFor(m => m.MainImage.DisplayName)
<img src="#MainImage.Path" alt="#MainImage.DisplayName" />
}
// Secondary files
#Html.TextBoxFor(m => m.SecondaryFiles, new { type = "file", multiple = "multiple" })
#Html.ValidationMessageFor(m => m.SecondaryFiles)
for (int i = 0; i < Model.SecondaryImages.Count; i++)
{
#Html.HiddenFor(m => m.SecondaryImages[i].ID)
...
}
<input type="submit" value="Save" />
}
And the controller POST method
public ActionResult Edit(FurnitureVM model)
{
// Save the files
if (model.MainFile != null && model.MainFile.ContentLength > 0)
{
string displayName = model.MainFile.FileName;
string extension = Path.GetExtension(displayName)
string fileName = string.Format("{0}{1}", Guid.NewGuid(), extension)
string path = Path.Combine("~/Images/", fileName);
model.MainFile.SaveAs(Server.MapPath(path));
model.MainImage = new ImageVM() { Path = path, DisplayName = displayName };
}
foreach (HttpPostedFileBase file in model.SecondaryFiles)
{
....
}
if (!ModelState.IsValid)
{
model.CategoryList = new SelectList(....); // repopulate the SelectList
return View(model);
}
// Get the data model from the database
Furniture furniture = db.Furniture.Where(x => x.FurnitureId == model.ID).FirstOrDefault()
// Update properties based on view model
furniture.Name = modell.Name;
...
// Update the main image
if (model.MainImage != null && !model.MainImage.ID.HasValue)
{
FurnitureImages image = new FurnitureImages()
{
image.Path = model.MainImage.Path;
image.DisplayName = model.MainImage.DisplayName;
image.IsMainImage = true;
furniture.Images.Add(image);
}
// Update secondary images
IEnumerable<ImageVM> newImages = model.SecondaryImages.Where(x => x.ID == null);
foreach (ImageVM image in newImages)
{
.... // add to the collection
}
// Save and redirect
}

Html.BeginForm POST overwrites image data when new image is not specified?

This is my first post to StackOverflow. I hope this is useful.
I have a Razor view that is intended to allow editing of the displayable properties of a model containing either pre-defined values or null values. The view should not change the contents of the model's properties unless the user changes them intentionally by editing them on in the UI based on the view. The view behaves correctly, except with regard to a property of type byte[] that contains image data: Model.ImageData
#using (Html.BeginForm("Edit", "Admin", FormMethod.Post, new { enctype = "multipart/form-data" } ))
{
#Html.EditorForModel()
<div class="editor-label">Image</div>
<div class="editor-field">
#if (Model.ImageData == null)
{
#: No image has been assigned in the database.
}
else
{
<img width="150" height="150" src="#Url.Action("GetImage", "Product", new { Model.ID} )" />
}
<div>Upload new image: <input type="file" name="Image" /></div>
</div>
<input type="submit" value="Save" />
}
The above view works as intended for all properties in the model except Model.ImageData. In this case, posting causes any previously set Model.ImageData to be set to null. I have confirmed that the Model.ImageData is set to null during post by verifying that prior to posting, Model.ImageData contains a valid byte array (with the expected image).
The controller code for the above view is:
public ViewResult Edit(int id)
{
Product product = repository.Products.FirstOrDefault(p => p.ID == id);
// breakpoint here shows that all model properties including product.ImageData are populated and valid.
return View(product);
}
[HttpPost]
public ActionResult Edit(Product product, HttpPostedFileBase Image)
{
if (ModelState.IsValid)
{
// breakpoint here shows that product.ImageData is null (but all other model properties are still populated with data).
if (Image != null)
{
product.ImageMimeType = Image.ContentType;
product.ImageData = new byte[Image.ContentLength];
Image.InputStream.Read(product.ImageData, 0, Image.ContentLength);
}
repository.SaveProduct(product);
TempData["Message"] = string.Format("{0} has been saved", product.Name);
return RedirectToAction("Index");
}
else
{
return View(product);
}
}
And here is the respository code that updates the model (though the model is changing before this code is called):
public void SaveProduct(Product product)
{
if (product.ID == 0)
{
context.Products.Add(product); // why doesn't this try to save ID = 0 to the ID field of the product in the database??
}
else
{
Product dbEntry = context.Products.Find(product.ID);
if (dbEntry != null)
{
dbEntry.Name = product.Name;
dbEntry.Description = product.Description;
dbEntry.Category = product.Category;
dbEntry.Price = product.Price;
dbEntry.ImageData = product.ImageData;
dbEntry.ImageMimeType = product.ImageMimeType;
}
}
context.SaveChanges();
}
What am I doing wrong?
This is really where you should consider using a ViewModel class instead. But to keep your current ways of doing things with minimal changes, try modifying the SaveProduct() method to the following:
public void SaveProduct(Product product, bool updateImage = false)
{
context.Products.Attach(product);
// mark product as modified
var entry = context.Entry(product);
entry.State = EntityState.Modified;
entry.Property(e => e.ImageData).IsModified = updateImage;
entry.Property(e => e.ImageMimeType).IsModified = updateImage;
context.SaveChanges();
}
and modify the controller code to:
...
var updateImage = false;
if (Image != null)
{
updateImage = true;
product.ImageMimeType = Image.ContentType;
product.ImageData = new byte[Image.ContentLength];
Image.InputStream.Read(product.ImageData, 0, Image.ContentLength);
}
repository.SaveProduct(product, updateImage);
....

MVC 4 ajax form image upload fails

I am trying to add an image by using MVC 4 ajax form, but it always returns null value. I added my model, controller and view.
My View
#using (Ajax.BeginForm("Create", "Images", new AjaxOptions { HttpMethod = "Post", OnSuccess = "OnSuccess", OnFailure = "OnFailure", UpdateTargetId = "messageDiv" }, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="editor-field">
#Html.LabelFor(model => model.Image.Description, new { #class = "control-label" })
<div class="controls">
#Html.TextBoxFor(model => model.Image.Description)
</div>
#Html.TextBoxFor(model => model.FileImage, new { type = "file" })
#Html.ValidationMessageFor(model => model.FileImage)
</div>...
}
My Model
public class ImageViewModel
{
public IList<Image> Images { get; set; }
public Image Image { get; set; }
public HttpPostedFileBase FileImage { get; set; }
}
My Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ImageViewModel model, HttpPostedFileBase FileImage)
{
if (ModelState.IsValid)
{
var x = FileImage.FileName;
var imageUrl = Path.GetFileName(model.FileImage.FileName);
...
}
}
In this example, I could not get the FileName. it returns always null value. Could you help me to solve this problem. I will be very happy.
I would prefer read the image using the request intead of trying to bind that to a model,
public ActionResult Create(ImageViewModel model)
{
if (Request.Files != null)
{
HttpPostedFileBase file = Request.Files[0]; //assuming that's going to be the first file
if (file.ContentLength > 0)
{
string fileName = Path.GetFileName(file.FileName);
string directory = Server.MapPath("/"); //change ths to your actual upload folder
file.SaveAs(Path.Combine(directory, fileName));
}
}
}

File Uploading in Asp.Net MVC

I am trying to make a file uploading page in my MVC project. First of all i want to manage this locally.
My Questions are:
1- Here is my controller and view. Is there any thing that I have to do to make this code work? I mean defining a model or using jquery, etc. What is the process when a file is being uploaded?
[HttpPost]
public ActionResult FileUpload(HttpPostedFileBase uploadFile)
{
if (uploadFile.ContentLength > 0)
{
string filePath = Path.Combine(HttpContext.Server.MapPath("C:/Users/marti/../PhotoGallery/myimages"),
Path.GetFileName(uploadFile.FileName));
uploadFile.SaveAs(filePath);
}
return View();
}
Here is the View:
<input name="uploadFile" type="file" />
<input type="submit" value="Upload File" />
2- When i debug this, It never goes to controller.
You may need the enctype='multipart/form-data' on your view form:
#model ImageModel
#{
ViewBag.Title = "New Image";
}
<div class="content-form-container width-half">
<form id='PropertiesForm' action='#Url.Action(ImageController.Actions.Add, ImageController.Name)' method='post' enctype='multipart/form-data' class='content-form'>
#Html.Partial("ImageName")
<fieldset class='content-form-1field'>
<div class='legend'>
file to upload
</div>
#Html.LabelledFileInput(ImageView.FileName, string.Empty)
</fieldset>
<div class='buttons'>
#Html.Button("button-submit", "submit")
</div>
</form>
</div>
#section script{
#Html.JavascriptInclude("~/js/image/new.min.js")
}
And here is my controller code:
[HttpPost]
[MemberAccess]
public ActionResult Add()
{
var name = ImageView.ImageName.MapFrom(Request.Form);
if (Request.Files.Count == 0)
{
RegisterFailureMessage("No file has been selected for upload.");
return ValidationFailureAdd(name);
}
var file = Request.Files[0];
if (file == null || file.ContentLength == 0)
{
RegisterFailureMessage("No file has been selected for upload or the file is empty.");
return ValidationFailureAdd(name);
}
var format = ImageService.ImageFormat(file.InputStream);
if (format != ImageFormat.Gif && format != ImageFormat.Jpeg && format != ImageFormat.Png)
{
RegisterFailureMessage("Only gif, jpg and png files are supported.");
return ValidationFailureAdd(name);
}
if (query.HasName(name))
{
RegisterFailureMessage(string.Format("Image with name '{0}' already exists.", name));
return ValidationFailureAdd(name);
}
using (var scope = new TransactionScope())
{
var id = Guid.NewGuid();
var fileExtension = ImageService.FileExtension(format);
Bus.Send(new AddWikiImageCommand
{
Id = id,
Name = name,
FileExtension = fileExtension
});
var path = Path.Combine(ApplicationConfiguration.MediaFolder,
string.Format("{0}.{1}", id.ToString("n"), fileExtension));
if (System.IO.File.Exists(path))
{
System.IO.File.Delete(path);
}
file.SaveAs(path);
scope.Complete();
}
return RedirectToAction(Actions.Manage);
}
There are some custom bits in there so you can ignore those. The gyst of what you need should be there.
HTH

Resources