I am aiming to create a form where users can upload an image along with some data fields. Currently, I can only get either the image or the data fields to work separately. The following code allows me to upload an image to my SQL database as binary data. I need assistance in uploading both the data fields and the image together within the same form. Thank you in advance.
View
<form ng-submit="submitItem()" enctype='multipart/form-data'>
<input class="form-control" type="text" ng-model="itemName" placeholder="Name" />
<input class="form-control" type="text" ng-model="itemCategory" placeholder="Category" /><br />
<input class="form-control" type="text" ng-model="itemDescription" placeholder="Description..." />
<input id="fileupload" class="form-control" type="file" ng-model="imageUrl" placeholder="Image" />
<input class="form-control" type="number" ng-model="itemPrice" placeholder="Price" /><br />
<input class="btn btn-danger" type="submit" value="Add Item" />
ApiController
public class apiItemsController : ApiController
{
ItemInterface _adapter;
public apiItemsController()
{
_adapter = new ItemDataAdapter();
}
public apiItemsController(ItemInterface adapter)
{
_adapter = adapter;
}
//// GET api/<controller>
public IHttpActionResult Get()
{
var items = _adapter.GetItems();
return Ok(items);
}
// GET api/<controller>/5
public IHttpActionResult Get(int id)
{
Item item = new Item();
item = _adapter.GetItem(id);
if (item == null)
{
return NotFound();
}
return Ok(item);
}
//POST
public async Task<object> PostFile()
{
if (!Request.Content.IsMimeMultipartContent())
throw new Exception();
var provider = new MultipartMemoryStreamProvider();
var result = new { files = new List<object>() };
var item = new Item();
await Request.Content.ReadAsMultipartAsync(provider)
.ContinueWith(async (a) =>
{
foreach (var file in provider.Contents)
{
var filename = file.Headers.ContentDisposition.FileName.Trim('\"');
var contentType = file.Headers.ContentType.ToString();
await file.ReadAsByteArrayAsync().ContinueWith(b =>
{
item.Image = b.Result;
});
}
}).Unwrap();
new ItemDataAdapter().PostNewItem(item);
return result;
}
Main Controller
app.controller('MainCtrl', function ($scope, $location, $anchorScroll, $modal, $ekathuwa, $q, Item, Message, $http) {
$scope.itemArray = null;
$http.get("api/apiItems").success(function (data) {
$scope.itemArray = data;
});
var url = "api/apiItems/File",
uploadButton = $('<button/>')
.addClass('btn btn-primary')
.prop('disabled', true)
.text('Processing...')
.on('click', function () {
var $this = $(this),
data = $this.data();
$this.off('click').text('Abort').on('click', function () {
$this.remove();
data.abort();
});
data.submit().always(function () {
$this.remove();
});
});
$('#fileupload').fileupload({
url: url,
dataType: 'json',
autoUpload: true,
maxFileSize: 5000000, // 5 MB
disableImageResize: /Android(?!.*Chrome)|Opera/
.test(window.navigator.userAgent),
previewMaxWidth: 100,
previewMaxHeight: 100,
previewCrop: true
}).on('fileuploadadd', function (e, data) {
data.context = $('<div/>').appendTo('#files');
$.each(data.files, function (index, file) {
var node = $('<p/>')
.append($('<span/>').text(file.name));
if (!index) {
node
.append('<br>')
.append(uploadButton.clone(true).data(data));
}
node.appendTo(data.context);
});
}).on('fileuploadprocessalways', function (e, data) {
var index = data.index,
file = data.files[index],
node = $(data.context.children()[index]);
if (file.preview) {
node.prepend('<br>').prepend(file.preview);
}
if (file.error) {
node.append('<br>').append($('<span class="text-danger"/>').text(file.error));
}
if (index + 1 === data.files.length) {
data.context.find('button').text('Upload').prop('disabled', !!data.files.error);
}
}).on('fileuploadprogressall', function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#progress .progress-bar').css('width', progress + '%');
}).on('fileuploaddone', function (e, data) {
$.each(data.result.files, function (index, file) {
if (file.url) {
var link = $('<a>').attr('target', '_blank').prop('href', file.url);
$(data.context.children()[index]).wrap(link);
} else if (file.error) {
var error = $('<span class="text-danger"/>').text(file.error);
$(data.context.children()[index]).append('<br>').append(error);
}
});
}).on('fileuploadfail', function (e, data) {
$.each(data.files, function (index, file) {
var error = $('<span class="text-danger"/>').text('File upload failed.');
$(data.context.children()[index]).append('<br>').append(error);
});
}).bind('fileuploaded', function (e, data) {
console.log(data);
if (data._response.textStatus === "success") {
for (var i = 0; i < data._response.jqXHR.responseJSON.files.length; i++) {
ko.observable(file.name), id: ko.observable(file.id) });
}
$('#progress .progress-bar').css('width', '0%');
}
}).prop('disabled', !$.support.fileInput)
.parent().addClass($.support.fileInput ? undefined : 'disabled');
DataAdapter
public class ItemDataAdapter : ItemInterface
{
public List<Item> GetItems()
{
ApplicationDbContext db = new ApplicationDbContext();
List<Item> model = new List<Item>();
model = db.Items.ToList();
return model;
}
public Item GetItem(int id)
{
ApplicationDbContext db = new ApplicationDbContext();
Item model = new Item();
model = db.Items.Where(j => j.ItemId == id)
.FirstOrDefault();
return model;
}
public List<Item> PostNewItem( Item newItem)
{
ApplicationDbContext db = new ApplicationDbContext();
db.Items.Add(newItem);
db.SaveChanges();
return db.Items.ToList();
}
Class
public class Item
{
public int ItemId { get; set; }
public string ItemName { get; set; }
public string ItemDescription { get; set; }
public int ItemPrice { get; set; }
public byte[] Image { get; set; }
public string ItemCategory { get; set; }
public bool Hidden { get; set; }
}