Asp.net mvc provider hosted app-upload a file - c#

I have a provider hosted app (asp.net MVC) and am trying to upload a file using a form but nothing works.ie the HttpPostedFileBase is always NULL.
Kindly assist.
Here the code I’m using,
#using (Html.BeginForm("Create", "StudentProgress", routeValues,FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="modal-body">
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.fk_level_register)
#Html.HiddenFor(model => model.date_modified)
#Html.HiddenFor(model => model.done_by)
<label for="file">Filename:</label>
<input type="file" name="upload" id="file" style="width:240px" />
<div class="form-group">
#Html.LabelFor(model => model.submission_deadline_date, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.submission_deadline_date)
#Html.ValidationMessageFor(model => model.submission_deadline_date)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.period_covered, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.period_covered, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.period_covered)
</div>
</div>
}

Instead of using File property as string datatype you can use HttpPostFileBasedatatype
ClassModel:
public DateTime submission_deadline_date { get; set; }
public string period_covered { get; set; }
public HttpPostedFileBase File { get; set; }
public string fk_level_register { get; set; }
public DateTime date_modified { get; set; }
public string done_by { get; set; }
Controler:
[HttpPost]
public ActionResult Create(Period collection)
{
string fpath = "";
try
{
if (Request.Files.Count > 0)
{
try
{
HttpPostedFileBase file = collection.File;
string fname;
// want to check extension then use this method
//if (CheckExtension(file.ContentType.ToLower()))
//{
// Checking for Internet Explorer
string extension = System.IO.Path.GetExtension(file.FileName);
if (Request.Browser.Browser.ToUpper() == "IE" || Request.Browser.Browser.ToUpper() == "INTERNETEXPLORER")
{
string[] testfiles = file.FileName.Split(new char[] { '\\' });
fname = Guid.NewGuid() + extension; //+ testfiles[testfiles.Length - 1];
}
else
{
fname = Guid.NewGuid() + extension; //+ file.FileName;
}
// Get the complete folder path and store the file inside it.
fname = System.IO.Path.Combine(Server.MapPath("~/Content/"), fname);
file.SaveAs(fname);
return Content("Successfully Uploaded");
//}
}
catch (Exception ex)
{
return Content("Error occurred. Error details: " + ex.Message);
}
}
}
catch (Exception)
{
return Content(Response.StatusCode.ToString() + " Bad Requrest error." + fpath);
}
return Content("No files selected.");
}
public bool CheckExtension(string Ext)
{
if (Ext == "application/pdf")
{
return true;
}
else if (Ext == "text/plain")
{
return true;
}
else if (Ext == "application/msword")
{
return true;
}
else if (Ext == "application/vnd.openxmlformats-officedocument.wordprocessingml.document")
{
return true;
}
else
{
return false;
}
}
View: in view only small change you need to do
#using (Html.BeginForm("Create", "Home", null, FormMethod.Post, new { id = "formU", enctype = "multipart/form-data" })){
#Html.AntiForgeryToken()
<div class="modal-body">
<div class="form-horizontal">
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.fk_level_register)
#Html.HiddenFor(model => model.date_modified)
#Html.HiddenFor(model => model.done_by)
<label for="file">Filename:</label>
<input type="file" name="File" id="File" style="width:240px" />
#*#Html.EditorFor(model => model.File, new { htmlAttributes = new { #type="file", #class = "form-control", #placeholder = "File path" } })*#
<div class="form-group">
#Html.LabelFor(model => model.submission_deadline_date, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.submission_deadline_date)
#Html.ValidationMessageFor(model => model.submission_deadline_date)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.period_covered, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.period_covered, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.period_covered)
</div>
</div>
<div class="form-group">
<input id="submit" type="submit" value="Submit" class="btn btn-success" />
</div>
</div>
</div>}
you can also download source code from git hub repository click here

Since you are using a provider hosted app, why not use this approach?
https://msdn.microsoft.com/en-us/library/office/dn904536.aspx

Related

The controller does not receive data from json

I'm developing an administration page and I'm having trouble receiving my data from json.
I have a Create view and inside it I created a script to show my partial views when selecting a certain type. But when I select the Hotel type, my controller is not receiving the data. When I select the other types, it works well.
Can anyone tell me what the problem is?
My Code:
Create.cshtml
#model ProjetoFinal.Models.Item
#{
ViewBag.Title = "";
}
<h2>#Resource.Criar</h2>
Português |
Inglês
<br />
#using (Html.BeginForm("Create", "Trans", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
<div class="form-group">
#Html.LabelFor(model => model.Titulo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Titulo, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Titulo, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Descricao, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextAreaFor(model => model.Descricao, new { #class = "form-control", #id = "Descricao" })
#Html.ValidationMessageFor(model => model.Descricao, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Main_Image, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="col-md-10">
<input type="file" name="imagem_principal" id="createimageinput" />
#Html.ValidationMessageFor(model => model.Main_Image, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Localidade, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Localidade, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Localidade, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Endereco, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Endereco, new { htmlAttributes = new { #id = "Endereco", #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Endereco, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Latitude, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Latitude, new { htmlAttributes = new { #id = "Latitude", #class = "form-control", #readonly = "readonly" } })
#Html.ValidationMessageFor(model => model.Latitude, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Longitude, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Longitude, new { htmlAttributes = new { #id = "Longitude", #class = "form-control", #readonly = "readonly" } })
#Html.ValidationMessageFor(model => model.Longitude, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Tipo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<!--Ao escolher o tipo vai aparecer os campos respetivos dessa categoria
atraves da funcao ddldropdown-->
#Html.DropDownListFor(model => model.Tipo, new SelectList(Model.tipos, "ID", "Tipo"), Resource.Selecionar_Tipo, htmlAttributes: new { #id = "ddldropdown", #class = "form-control" })
</div>
</div>
<div id="partialDiv">
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" id="btnsave" value="#Resource.Criar" class="btn btn-default" />
</div>
</div>
</div>
#section Scripts
{
<!--Script to add Views from the Others folder in the "partialDiv"-->
<script type="text/javascript">
$("#ddldropdown").change(function () {
var txt = $("#ddldropdown option:selected").text();
if (txt == null || txt == "Selecionar Tipo")
$('#partialDiv').html('');
else if (txt == "Teatro" || txt == "Feira" || txt == "Exposição" || txt == "Hotel" || txt == "Cinema" || txt == "Musica") {
$.ajax({
type: 'get',
url: '/Outros/Create_' + txt,
dataType: 'html',
success: function (html) {
$('#partialDiv').html(html);
}
});
}
else if (txt == "Parques/Percursos Pedestres") {
$.ajax({
type: 'get',
url: '/Outros/Create_Percurso',
dataType: 'html',
success: function (html) {
$('#partialDiv').html(html);
}
});
}
else {
$.ajax({
type: 'get',
url: '/Outros/Create_Other',
dataType: 'html',
success: function (html) {
$('#partialDiv').html(html);
}
});
}
});
</script>
<!--Script to submit partialDiv data-->
<script type="text/javascript">
window.jQuery(document).ready(function () {
$('#btnsave').click(function () {
var txt = $("#ddldropdown option:selected").text();
var frm = $("form");
var data = new FormData($("form")[0]);
if (txt == "Teatro" || txt == "Feira" || txt == "Exposição" || txt == "Hotel" || txt == "Cinema" || txt == "Musica") {
var files = $("#createimageinput").get(0).files;
// Add the uploaded file to the form data collection
if (files.length > 0) {
for (f = 0; f < files.length; f++) {
data.append("imgfile", files[f]);
}
}
$.ajax({
url: '/Outros/Create_' + txt,
method: "POST",
processData: false,
data: data,
dataType: 'html',
contentType: false,
});
}
else if (txt == "Parques/Percursos Pedestres")
{
$.ajax({
url: '/Outros/Create_Percurso',
method: "POST",
processData: false,
data: data,
dataType: 'html',
contentType: false,
});
}
else
{
if (txt != null || txt != "Selecionar Tipo")
{
$.ajax({
url: '/Outros/Create_Other',
method: "POST",
processData: false,
data: data,
dataType: 'html',
contentType: false,
});
}
}
});
});
</script>
<!--Script to place the Autocomplete at the Address-->
<script>
// This example requires the Places library. Include the libraries=places
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCvSxmjQNuUVyhYFJ8SmXHa0sQKgpiLBLA&libraries=places">
function initMap() {
google.maps.event.addDomListener(window, 'load', function () {
var options = {
types: ['geocode'],
componentRestrictions: { country: "pt" }
};
var input = document.getElementById('Endereco');
var autocomplete = new google.maps.places.Autocomplete(input, options);
google.maps.event.addListener(autocomplete, 'place_changed', function () {
var near_place = autocomplete.getPlace();
document.getElementById('Latitude').value = near_place.geometry.location.lat();
document.getElementById('Longitude').value = near_place.geometry.location.lng();
});
});
}
$("#Endereco").change(function () {
document.getElementById('Latitude').value = '';
document.getElementById('Longitude').value = '';
});
</script>
<!--Google API-->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCvSxmjQNuUVyhYFJ8SmXHa0sQKgpiLBLA&libraries=places&callback=initMap"
async defer></script>
<script type="text/javascript">
$('#btnsave').click(function () {
var form = $("#formH");
var url = form.attr("action");
var formData = form.serialize();
$.post(url, formData, function (data) {
$("#msg").html(data);
});
})
</script>
}
<div>
#Html.ActionLink(Resource.Voltar, "Index")
</div>
}
Create_Hotel.cshtml
#model ProjetoFinal.Models.Hotel
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
#using (Html.BeginForm("Create_Hotel", "Outros", FormMethod.Post))
{
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Outras_Imagens, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="col-md-10">
<input type="file" name="images" multiple="multiple" id="imagens"/>
#Html.ValidationMessageFor(model => model.Outras_Imagens, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Preco, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Preco, new { htmlAttributes = new { #type = "number", #min = "0", #step = "0.01", #value = "0", #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Preco, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Tipo_Hotel, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Tipo_Hotel, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Tipo_Hotel, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group" id="div_comodidades">
#Html.LabelFor(model => model.Comodidades, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10" id="divCom">
<div class="input-group">
<span class="input-group-btn">
#Html.EditorFor(model => model.Comodidades, new { htmlAttributes = new { #id = "comodidades", #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Comodidades, "", new { #class = "text-danger" })
<input type="button" class="btn btn-primary" id="com" value="+" onclick="addComodidades()" />
</span>
</div>
</div>
</div>
<div class="form-group" id="div_condicoes">
#Html.LabelFor(model => model.Condicoes, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10" id="divCon">
<div class="input-group">
<span class="input-group-btn">
#Html.EditorFor(model => model.Condicoes, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Condicoes, "", new { #class = "text-danger" })
<input type="button" class="btn btn-primary" value="+" onclick="addCondicoes()" />
</span>
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Telefone1, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Telefone1, new { htmlAttributes = new { #type = "number", #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Telefone1, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Telefone2, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Telefone2, new { htmlAttributes = new { #type = "number", #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Telefone2, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Email, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Email, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Avaliacao, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Avaliacao, new { htmlAttributes = new { #type = "number", #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Avaliacao, "", new { #class = "text-danger" })
</div>
</div>
</div>
#section Scripts
{
<script type="text/javascript">
var cont = 0;
var cont1 = 0;
//function to add more fields for the user to enter more comodidades
function addComodidades() {
cont++;
$("#div_comodidades").append(`<div class="col-md-10" id="campo` + cont + `" style="margin-left:16.7%">
<div class="input-group">
<span class="input-group-btn">
<input class="form-control text-box single-line" name="Comodidades" placeholder="Comodidades" type="text" value="" id="input_comodidades` + cont + `"/>
<span class="field-validation-valid text-danger" data-valmsg-for="Comodidades" data-valmsg-replace="true"></span>
<input type="button" id="` + cont + `" class="btn btn-primary" value="-" style="padding-left:15px;"/>
</span>
</div>
</div>`);
}
//function to add more fields for the user to enter more condicoes
function addCondicoes() {
cont1++;
$('#div_condicoes').append(`<div class="col-md-10" id="campo1` + cont1 + `" style="margin-left:16.7%">
<div class="input-group">
<span class="input-group-btn">
<input class="form-control text-box single-line" name="Condicoes" placeholder="Condicoes" type="text" value="" id="input_condicoes` + cont1 + `" />
<span class="field-validation-valid text-danger" data-valmsg-for="Condicoes" data-valmsg-replace="true"></span>
<input type="button" id="` + cont1 + `" class="btn btn-primary" value="-" style="padding-left:15px;"/>
</span>
</div>
</div>`);
}
//function to remove the comodidades field that the user added
$('#div_comodidades').on('click', '.btn-primary', function () {
var button_id = $(this).attr("id");
$('#campo' + button_id + '').remove();
});
//function to remove the condicoes field that the user added
$('#div_condicoes').on('click', '.btn-primary', function () {
var button_id = $(this).attr("id");
$('#campo1' + button_id + '').remove();
});
</script>
}
}
#{
Layout = null;
}
TransController.cs
public class TransController : Controller
{
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(FormCollection formCollection)
{
Item item = new Item();
//add the database
}
}
OutrosController.cs
public class OutrosController : Controller
{
[HttpGet]
public ActionResult Create_Hotel()
{
Hotel hotel = new Hotel();
return View(hotel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create_Hotel(Hotel hotel, HttpPostedFileBase[] images)
{
//add the database
return View(hotel);
}
}
(Model) Hotel.cs
public class Hotel
{
public int ID { get; set; }
public String Preco { get; set; }
public String Comodidades { get; set; }
public List<String> array_comodidades { get; set; }
public String Condicoes { get; set; }
public List<String> array_condicoes{ get; set; }
[Display(Name = "Telefone")]
public int? Telefone1 { get; set; }
[Display(Name = "Telemovel/Fax")]
public int? Telefone2 { get; set; }
public String Email { get; set; }
public String Tipo_Hotel { get; set; }
[Range(0, 5)]
public String Avaliacao { get; set; }
public List<Imagem> Imagens { get; set; }
[Display(Name = "Imagens_Secundárias", ResourceType = typeof(Resource))]
public String Outras_Imagens { get; set; }
public class TransmontanosDBContext : DbContext
{
public DbSet<Hotel> Transmontanos { get; set; }
}
}
Problem:
Your ajax request specifies type, url, dataType and a callback success function but it never actually sends any of the form data with it (not sure why these fields are in a form any way if youre not using the form to submit the data to the server- but that's a different problem than your posting about.
To fix your issue, you should change your ajax request to a POST instead of GET and include your model data with it as follows:
var model = { Id = $("#Id").val(),
Preco = $("#Preco").val(),
//populate the rest of your fields here just like Id
};
$.ajax({
type: "POST",
data: JSON.stringify(model),
url: '/Outros/Create_Percurso',
contentType: "application/json",
success: function (html) {
$('#partialDiv').html(html);
}
})

The model item passed into the dictionary is of type 'System.Collections.Generic.List'

I'm new to asp.net and this is my first application.
I'm developing an application that manages insurance requests. The model Request contains a file upload. the addDemand (adds a request)requires a member(adherent) to be logged in. Every time I try to run the addDemande I get the error:
The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[Mutuelle.Domain.Entities.Demande]', but this dictionary requires a model item of type 'Mutuelle.Domain.Entities.Demande'.
Here's the controller:
public ActionResult AddDemande()
{
Demande demande = new Demande();
return View(demande);
}
[HttpPost]
public ActionResult AddDemande([Bind(Exclude = "fichier")]Demande demande, HttpPostedFileBase fichier)
{
try
{
if (!ModelState.IsValid)
{
return View();
}
else
{
BinaryReader fichierReader = new BinaryReader(fichier.InputStream);
byte[] fichiers = fichierReader.ReadBytes(fichier.ContentLength);
demande.fichier = fichiers;
AdherentDService adherentService = new AdherentDService();
Adherent adherent = (Adherent)Session["logedAd"];
demande.nomBeneficiaire = adherent.nom;
demande.eMailBeneficiaire = adherent.eMail;
demande.beneficiare = adherent;
adherent.listDemandes.Add(demande);
adherentService.Updateadherent(adherent);
demande.beneficiare = adherent;
adherentService.CreateaDemande(demande);
Session.Remove("logedAd");
Session.Add("logedAd", adherent);
return RedirectToAction("Demandes");
}
}
catch
{
return RedirectToAction("Index", "Home");
}
}
And here's the View:
model Mutuelle.Domain.Entities.Demande
#{
ViewBag.Title = "AddDemande";
}
<h2>AddDemande</h2>
#using (Html.BeginForm("AddDemande", "Adherent", FormMethod.Post, new { #enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Demande</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.Nomrubrique, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Nomrubrique)
#Html.ValidationMessageFor(model => model.Nomrubrique)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.fichier, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input style="margin-left:0px;cursor:pointer;" type="file" name="fichier" id="fichier" />
</div>
</div>

Multiple posts on a single page asp.net MVC with partial views

We've got a page which currently contains a four or five partial views, but is something that could grow. At the moment, there's two POST actions, for two entirely different database functions.
If we try doing the create function on another, the redirect then results in an "Object reference not set to an instance of an object." error, which is then relating to the other POST partial view.
Is there a way to stop this? Essentially, it seems to me that the post for one partial view is trying to interact with the other. Any ideas?
Thanks
Bulletins Controller for Creating:
[HttpPost]
public ActionResult CreateMain(BulletinsViewModel viewModel)
{
if (ModelState.IsValid)
{
BulletinsContext.tblBulletins.Add(new tblBulletin
{
ID = viewModel.BulletinID,
BulletinDisplayDate = viewModel.BulletinDisplayDate,
BulletinFilename = viewModel.MainBulletinName,
IsSixthForm = viewModel.IsSixthForm
});
//For loop to delete bulletins
//If bulletin folder has more than 10 files in
//Delete the oldest file, itererate till only 10 remain
{
DirectoryInfo dir = new DirectoryInfo(#"D:\Inetpub\WWWroot\intranet\Dashboard\Dashboard\Files\Bulletins");
List<FileInfo> filePaths = dir.GetFiles().OrderByDescending(p => p.CreationTime).ToList();
for (int index = filePaths.Count() - 1; index > 9; index--)
{
var fileNames = filePaths[index].Name;
//Delete from directory
filePaths[index].Delete();
//Remove from collection to restart the loop
filePaths.RemoveAt(index);
}
}
//Save changes to database
BulletinsContext.SaveChanges();
//Return to main bulletins index page
return RedirectToAction("~/Home/Index");
}
return View(viewModel);
}
Bulletins Create View:
#model Dashboard.Viewmodels.BulletinsViewModel
#{
ViewBag.Title = "Create";
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.BulletinDisplayDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.BulletinDisplayDate, new { htmlAttributes = new { #class = "form-control", #id = "datepicker-basic", #readonly = "readonly" } })
#Html.ValidationMessageFor(model => model.BulletinDisplayDate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.MainBulletinName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="input-group">
#Html.EditorFor(model => model.MainBulletinName, new { htmlAttributes = new { #class = "form-control", #Value = "Select File...", #readonly="readonly" } })
<span class="input-group-addon" href="javascript:;" onclick="moxman.browse({ fields: 'MainBulletinName', extensions: 'pdf', path: 'D:/Inetpub/WWWroot/intranet/Dashboard/Dashboard/Files/Bulletins' });" style="cursor: pointer;"><i class="fa fa-upload"></i></span>
#Html.ValidationMessageFor(model => model.MainBulletinName, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
}
<script type="text/javascript" src="~/Scripts/tinymce/plugins/moxiemanager/js/moxman.loader.min.js"></script>
Printer Credits Create Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult PrinterCredits(PrinterCreditsViewModel viewModel)
{
if (ModelState.IsValid)
{
//Send the email if credits are added..
//Create a bunch of variables for the email
//Create the email body etc
var fromAddress = "";
string toName = Request.Form["Username"].ToUpper();
string AmountOfCredits = Request.Form["AmountAdded"];
string Plural = "";
string Title = "";
string AddedByWho = User.Identity.Name.Split('\\')[1];
System.DateTime AddedWhen = DateTime.Now;
if (AmountOfCredits == "1")
{
Plural = " printer credit has ";
Title = "Printer Credit Added!";
}
else
{
Plural = " printer credits have ";
Title = "Printer Credits Added!";
}
var toEmail = toName + "";
var subject = AmountOfCredits + Plural + "been added to your account, " + toName;
string body = "";
//Create an SMTP client for sending an email
var smtp = new SmtpClient
{
Host = "",
Port = 25,
EnableSsl = false,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = true,
};
//Populate the SMTP client and encode the body for the HTML
using (var message = new MailMessage(fromAddress, toEmail)
{
Subject = subject,
Body = body,
IsBodyHtml = true,
BodyEncoding = System.Text.Encoding.UTF8
})
//Try to send the email. If sent, insert data.
//Redirect back to original page
//Take current printer credit from and update with fund + cost
try
{
//Link the viewmodel and the database together
PartialViewContext.tblPrinterCredits.Add(new tblPrinterCredit
{
Username = viewModel.Username,
AmountAdded = viewModel.AmountAdded,
AddedBy = AddedByWho,
AddedWhen = viewModel.AddedWhen,
Money = viewModel.AmountAdded * 0.02
});
Nullable<double> cost = viewModel.AmountAdded * 0.02;
//Update the printer credit fund and insert into tblOption
tblOption fund = (
from n in PartialViewContext.tblOptions
where n.ID == 1
select n).First();
fund.PrinterCreditFund = fund.PrinterCreditFund + cost;
PartialViewContext.SaveChanges();
message.CC.Add("");
smtp.Send(message);
Response.Redirect("~/Home/Index");
}
//If it fails, go chicken oriental (only a redirect, will eventually become a crazy message)
catch
{
smtp.Send(message);
Response.Redirect("~/Home/Index");
}
}
return View(viewModel);
Printer Credits View:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="panel">
<div class="panel-heading">
<span class="panel-icon">
<i class="fa fa-print"></i>
</span>
Add Printer Credits - #Costings
</div>
<div class="panel-body">
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<label class="control-label col-md-3">User:</label>
<div class="col-xs-8">
#Html.EditorFor(model => model.Username, new { htmlAttributes = new { #class = "form-control", #id = "Username", #name = "Username", #maxlength = "6" } })
#Html.ValidationMessageFor(model => model.Username, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<label class="control-label col-md-3">Amount:</label>
<div class="col-xs-8">
#Html.EditorFor(model => model.AmountAdded, new { htmlAttributes = new { #class = "form-control", #id = "AmountAdded", #onkeyup = "Update()", #Value = 0 } })
#Html.ValidationMessageFor(model => model.AmountAdded, "", new { #class = "text-danger", #type="number" })
</div>
</div>
<div class="form-group">
<label class="control-label col-md-3">Cost:</label>
<div class="col-xs-8">
#Html.EditorFor(model => model.TotalCost, new { htmlAttributes = new { #class = "form-control", #id = "TotalCost", #readonly = "readonly", #Value = "0" } })
#Html.ValidationMessageFor(model => model.TotalCost, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-1 col-md-10">
<input type="submit" value="Add Printer Credits" class="btn btn-primary btn-gradient dark btn-block" />
#Html.EditorFor(model => model.AddedBy, new { htmlAttributes = new { #class = "form-control", #Value = User.Identity.Name.Split('\\')[1], #Style = "display: none;" } })
#Html.ValidationMessageFor(model => model.AddedBy, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
</div>
}
<script type="text/javascript">
$(document).ready(
function () {
Update();
$('#AmountAdded, #TotalCost')
.keyup(function () {
Update();
})
}
);
function Update() {
var cost = 2
var one = $('#AmountAdded'),
two = $('#TotalCost');
two.val(parseInt(one.val()) * cost / 100);
}
</script>
<script type="text/javascript">
document.getElementById('Username').focus()
</script>
Just figured out that I need to tell the form which action and controller to use, despite the fact two different controllers are running the views. But anyway, an example is:
#using (Html.BeginForm("CreateMain", "Bulletins", FormMethod.Post, new { }))

Adding a image to database in ASP.NET MVC 5

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

HttpPostedFileBase is always empty

I am trying to upload image files from my form along with other fields in my model. My HttpPostedFileBase collection is always empty and the count is 0.
I have referred many other questions relating to this in SO but somehow I am unable to find the solution.
View:
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.Id, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Id)
#Html.ValidationMessageFor(model => model.Id)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ProfileId, "ProfileId", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("ProfileId", String.Empty)
#Html.ValidationMessageFor(model => model.ProfileId)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Image1, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input name="fileuploadImage1" type="file" />
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Image2, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input name="fileuploadImage2" type="file" />
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Image3, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input name="fileuploadImage3" type="file" />
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Image4, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input name="fileuploadImage4" type="file" />
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Image5, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input name="fileuploadImage5" type="file" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,ProfileId,fileuploadImage1,fileuploadImage2,fileuploadImage3,fileuploadImage4,fileuploadImage5,Files")] HomepageSetting homepagesetting)
{
if (ModelState.IsValid)
{
try
{
List<String> imagesFilenames = new List<String>();
/*Lopp for multiple files*/
foreach (HttpPostedFileBase file in homepagesetting.Files)
{
/*Geting the file name*/
string filename = System.IO.Path.GetFileName(file.FileName);
/*Saving the file in server folder*/
file.SaveAs(Server.MapPath("~/Images/" + filename));
string filepathtosave = "Images/" + filename;
imagesFilenames.Add(filepathtosave);
}
if(imagesFilenames.Count == 1)
{
homepagesetting.Image1 = imagesFilenames[0];
}
else if (imagesFilenames.Count == 2)
{
homepagesetting.Image1 = imagesFilenames[0];
homepagesetting.Image2 = imagesFilenames[1];
}
else if (imagesFilenames.Count == 3)
{
homepagesetting.Image1 = imagesFilenames[0];
homepagesetting.Image2 = imagesFilenames[1];
homepagesetting.Image3 = imagesFilenames[2];
}
else if (imagesFilenames.Count == 4)
{
homepagesetting.Image1 = imagesFilenames[0];
homepagesetting.Image2 = imagesFilenames[1];
homepagesetting.Image3 = imagesFilenames[2];
homepagesetting.Image4 = imagesFilenames[3];
}
else if (imagesFilenames.Count == 5)
{
homepagesetting.Image1 = imagesFilenames[0];
homepagesetting.Image2 = imagesFilenames[1];
homepagesetting.Image3 = imagesFilenames[2];
homepagesetting.Image4 = imagesFilenames[3];
homepagesetting.Image5 = imagesFilenames[4];
}
ViewBag.Message = "File Uploaded successfully.";
}
catch
{
ViewBag.Message = "Error while uploading the files.";
}
db.HomepageSettings.Add(homepagesetting);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.ProfileId = new SelectList(db.Profiles, "Id", "name", homepagesetting.ProfileId);
return View(homepagesetting);
}
Model:
public partial class HomepageSetting
{
public int Id { get; set; }
//other model properties
public string Image1 { get; set; }
public string Image2 { get; set; }
public string Image3 { get; set; }
public string Image4 { get; set; }
public string Image5 { get; set; }
public virtual Profile Profile { get; set; }
public List<HttpPostedFileBase> Files { get; set; }
public HomepageSetting()
{
Files = new List<HttpPostedFileBase>();
}
}
Can any one point me to what I am doing wrong here?
Instead of foreach loop do it this way, it happens with foreach as i also faced this issue:
for (int i = 0; i < Request.Files.Count; i++)
{
HttpPostedFileBase myFile = Request.Files[i];
}
In MVC you always have to proper name of html element in order to work its default binding. In your case
fileupload control has name like fileuploadImage1 , fileuploadImage2 and that not present in your model so it is not binding.
I suggest that you should name all your file upload element name.
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.Id, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Id)
#Html.ValidationMessageFor(model => model.Id)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ProfileId, "ProfileId", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("ProfileId", String.Empty)
#Html.ValidationMessageFor(model => model.ProfileId)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Image1, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input name="files" type="file" />
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Image2, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input name="files" type="file" />
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Image3, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input name="files" type="file" />
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Image4, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input name="files" type="file" />
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Image5, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input name="files" type="file" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
Your action you have to do .
[HttpPost]
public ActionResult View1([Bind(Include = "Id,ProfileId,fileuploadImage1,fileuploadImage2,fileuploadImage3,fileuploadImage4,fileuploadImage5,Files")] HomepageSetting homepagesetting)
{
for (int i = 0; i < homepagesetting.Files.Count; i++)
{
if (homepagesetting.Files[i] != null)
{
}
}
return View();
}

Categories