Upload image to database - javascript

Im trying to figure out how I can upload a profile image to my database within my asp.net mvc web project.
The issues is that im getting a Data URI instead of an actual file upload and that the URI is generated inside my javascript and im not sure how I can pass URI aswell as the other input fields inside my form to the controller.
View - Form
#using (Html.BeginForm("Register", "Account", FormMethod.Post, new { #class = "form-horizontal", role = "form", enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<h4>Create a new account.</h4>
<hr />
#Html.ValidationSummary("", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(m => m.ProfilePicture, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
<div id="wrapper" style="margin-top: 20px;">
<div class="image-editor">
<input type="file" class="cropit-image-input">
<div class="cropit-preview"></div>
<div class="image-size-label">
Resize image
</div>
<div class="controls-wrapper">
<div class="slider-wrapper">
<span class="icon icon-image small-image"></span>
<input type="range" class="cropit-image-zoom-input custom">
<span class="icon icon-image large-image"></span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.UserName, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.UserName, new { #class = "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">
<div class="col-md-offset-2 col-md-10">
<input type="hidden" name="profilePicture" class="hidden-image-data">
<input type="submit" class="btn btn-default" value="Register"/>
</div>
</div>
}
Javascript below the Form
<script src="~/Scripts/jquery.cropit.js"></script>
<script>
$(function() {
$('.image-editor').cropit({
imageBackground: true,
imageBackgroundBorderWidth: 20,
initialZoom: 'image',
smallImage: 'stretch',
imageState: {
src: '/Images/ProfilePictures/no-img.png'
}
});
$('form').submit(function () {
var imageData = $('.image-editor').cropit('export');
// imageData containing the Data URI for the cropped image
$('.hidden-image-data').val(imageData);
});
});
</script>
Controller - Register
public async Task<ActionResult> Register([Bind(Exclude = "ProfilePicture")]RegisterViewModel model) {
if (ModelState.IsValid) {
// To convert the user uploaded Photo as Byte Array before save to DB
byte[] imageData = null;
if (Request.Files.Count > 0) {
HttpPostedFileBase poImgFile = Request.Files["ProfilePicture"];
using (var binary = new BinaryReader(poImgFile.InputStream)) {
imageData = binary.ReadBytes(poImgFile.ContentLength);
}
}
.... more code ....
}
}
Feel free to ask for more explanatory details.

A data URI is a non-binary encoding of binary data. That is the data you want.
It's probably base64 encoded so you can just base64 decode it on the server side before you write it.
There's code here to encode into and from base64
Here's the example code from the site linked above:
public class Base64Decoder
{
public static void Main ()
{
string inputText = "This is some text.";
Console.Out.WriteLine ("Input text: {0}", inputText);
byte [] bytesToEncode = Encoding.UTF8.GetBytes (inputText);
string encodedText = Convert.ToBase64String (bytesToEncode);
Console.Out.WriteLine ("Encoded text: {0}", encodedText);
byte [] decodedBytes = Convert.FromBase64String (encodedText);
string decodedText = Encoding.UTF8.GetString (decodedBytes);
Console.Out.WriteLine ("Decoded text: {0}", decodedText);
Console.Out.Write ("Press enter to finish.");
Console.In.ReadLine ();
return;
}
}

Related

Send img file to .net controller from <"img">

I am using adobe creative sdk image editor and .net for my project. When I edit a image, only <"img"> is changing but I am sending <"input file">. I tried two way, firstly I send data to <"input file"> and later send to controller. But I didnt. Secondary directly <"img"> file to controller but again didnt work.`
Index
#using (Html.BeginForm("Save", "Tweet", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>TweetModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Content, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Content, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Content, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="row">
<div class="col-md-10">
<input id="click-upload" name="file" type="file">
<div id="drop-area">
<p>Drop an image here!</p>
<p>(or click to upload)</p>
</div>
<img id="editable-image" onclick="read()" class="img-responsive">
</div>
</div>
<div class="col-md-12">
<button>Gönder</button>
</div>
}`
<script type="text/javascript">
function read()
{
var c = document.getElementById("editable-image");
document.getElementById("click-upload").innerHTML = c;
alert(document.getElementById("click-upload").size);
}
</script>
public ActionResult Save(Tweet tweetModel)
{
WebImage file = WebImage.GetImageFromRequest();
tweetModel.UserId = Convert.ToInt32(Session["UserId"]);
if (tweetModel.UserId > 0)
{
if (file.FileName !=null)
{
// code for saving the image file to a physical location.
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/Uploads/Image"), fileName);
file.Save(path);
// prepare a relative path to be stored in the database and used to display later on.
path = Url.Content(Path.Combine("~/Uploads/Image", fileName));
// save to db
tweetModel.Image = path;
}
CreateOrder(tweetModel);
}
return RedirectToAction("Index");
}

Showing a toast notification on form submission

I am new to ASP.NET MVC 5. I am having trouble displaying a toast notification when I submit a form in MVC 5. It does not display on the page after I click submit. This is the code:
Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Contact(ContactData formdata)
{
//what is supposed to happen when form is successful and there are no validation errors
if (ModelState.IsValid)
{
var data = new ContactData
{
FirstName = formdata.FirstName,
LastName = formdata.LastName,
Email = formdata.Email,
Message = formdata.Message
};
//add the message to the messages table and then save the changes
_dbContext.Messages.Add(data);
_dbContext.SaveChanges();
TempData["Success"] = "Success";
return RedirectToAction("Contact","Home");
}
return View(formdata); //else re display the form showing the validation errors
}
This is the JavaScript in the View:
#section Scripts{
<script>
$(document).ready(function () {
if (TempData.ContainsKey("Success")) {
toastr.success("Message Sent Successfully");
}
}
</script>
}
Note: I have implemented the form using HTML helper methods rather than JQuery. This is my form:
#using (Html.BeginForm("Contact", "Home", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
<br /><br />
#Html.AntiForgeryToken()
#Html.ValidationSummary() <!--shows a list of the validation errors-->
<div class="row col-sm-12 col-md-12 col-lg-12">
<div class="col-sm-4 col-md-4 col-lg-4">
<strong>Leave a Message:</strong>
</div>
<span class="clearfix"></span> <!--makes the content go to the left-->
<div class="form-group col-sm-4 col-md-4 col-lg-4" style="margin-left:4px;">
#Html.LabelFor(t => t.FirstName)
#Html.TextBoxFor(t => t.FirstName, new { #class = "form-control" })
#Html.ValidationMessageFor(t => t.FirstName, String.Empty, new { #style = "color:red;!important" })
</div>
<span class="clearfix"></span>
<div class="form-group col-sm-4 col-md-4 col-lg-4" style="margin-left:4px;">
#Html.LabelFor(t => t.LastName)
#Html.TextBoxFor(t => t.LastName, new { #class = "form-control" })
#Html.ValidationMessageFor(t => t.LastName, String.Empty, new { #style = "color:red;!important" })
</div>
<span class="clearfix"></span>
<div class="form-group col-sm-4 col-md-4 col-lg-4" style="margin-left:10px;">
#Html.LabelFor(m => m.Email)
#Html.TextBoxFor(m => m.Email, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Email, String.Empty, new { #style = "color:red;!important" })
</div>
<span class="clearfix"></span>
<div class="form-group col-sm-4 col-md-4 col-lg-4" style="margin-left:10px;">
#Html.LabelFor(m => m.Message)
#Html.TextAreaFor(m => m.Message, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Message, String.Empty, new { #style = "color:red;!important" })
</div>
<span class="clearfix"></span>
<div class="form-group col-sm-4 col-md-4 col-lg-4" style="margin-left:10px;">
<input id="btnRegister" type="submit" class="btn btn-success" value="Submit" />
</div>
</div>
}
I don't know what I am doing wrong. Thank you.
I believe the problem is that TempData is in your Controller, and would need to be handled in your View as a part of the Model, or, if you have access to to TempData in your view, you'd need to define it in a Razor block like this:
<script>
var jsTempDataSuccess = '#TempData["Success"]';
</script>
And then in your document ready, you can do this:
<script>
$(document).ready(function () {
if (jsTempDataSuccess && jsTempDataSuccess == "Success") {
toastr.success("Message Sent Successfully");
}
}
</script>
The expression TempData is server side code, So you should prefix it with #.
I like to render the script inside an if condition so that if TempData.ContainsKey("Success") returns false, the script will not be even rendered to the page (less script to compile and parse)
$(document).ready(function ()
{
#if(TempData.ContainsKey("Success"))
{
#:toastr.success("Message Sent Successfully");
}
});

How to open a dialog box after submit a form to show posted successfully - asp.net MVC

I'm working on a asp.net MVC project. I want to show user a dialog box after form posted, for user to understand if it was successful or not, and also if user wants to close the dialog box it would be possible.
I searched a lot and read something that I can return partial view but i'm not sure if partial view is what I need in this situation
my question is that is it possible to do it a way with java-script with .dialog() or if I should use partial view, then please give me a little explanation how it works.
I need something like this to show after user click on submit button
http://jsfiddle.net/db5SX/
here is my controller:
public ActionResult Index()
{
ViewBag.ResultMessage = TempData["ResultMessage"];
return View();
}
public ActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,Name,Email,Phone,Message,Date")] Contact_US contact_US)
{
if (ModelState.IsValid)
{
db.Contact_US.Add(contact_US);
db.SaveChanges();
TempData["ResultMessage"] = "POSTED SUCESSFULLY...! We WILL CONTACT YOU SOON.";
return RedirectToAction("Index");
}
return View(contact_US);
}
here is my view if needed:
<div class="form-group col-md-8">
<h3 class="txtformat padbot50px">Get in touch with us</h3>
<div class="text-danger message ">
#ViewBag.ResultMessage
</div>
#using (Html.BeginForm("Create", "Contact_Us", FormMethod.Post, new { #id = "contactusform" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2 txtformat" })
<div class="col-md-12">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Email, htmlAttributes: new { #class = "control-label col-md-2 txtformat" })
<div class="col-md-12">
#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.Phone, htmlAttributes: new { #class = "control-label col-md-2 txtformat" })
<div class="col-md-12">
#Html.EditorFor(model => model.Phone, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Phone, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group hidden">
#Html.LabelFor(model => model.Date, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Date, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Date, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Message, htmlAttributes: new { #class = "control-label col-md-2 txtformat" })
<div class="col-md-12 contactusmsg">
#Html.TextAreaFor(model => model.Message, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Message, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group contactuspostbtn">
<div class="col-md-12">
<input id="postcontactusmessage" type="submit" value="Send" class="btn btn-default" data-toggle="modal" data-target="#myModal" />
</div>
</div>
</div>
}
</div>
</div>
information of my layout if needed :
<script src="~/Scripts/jquery-3.1.0.min.js"></script>
<link href="~/Scripts/jquery-ui-1.12.1.custom/jquery-ui.css" rel="stylesheet" />
<script src="~/Scripts/jquery-ui-1.12.1.custom/jquery-ui.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<script src="~/Scripts/modernizr-2.6.2.js"></script>
<script src="~/Scripts/tinymce/tinymce.min.js"></script>
A good way to do this is to have it abstracted in a base controller and show the message in the _layouts.cshtml file, for example:
Create a base controller that will be inherited by all of your controllers
public class BaseController : Controller
{
public string SucccessMessage
{
get
{
return TempData["SuccessMessage"] as string;
}
set
{
TempData["SuccessMessage"] = value;
}
}
public string ErrorMessage
{
get
{
return TempData["ErrorMessage"] as string;
}
set
{
TempData["ErrorMessage"] = value;
}
}
}
In _Layouts.cshtml,
<div class="container body-content" id="bodyContainer">
<div class="spacer"></div>
#if (#TempData["SuccessMessage"] != null)
{
<div class="alert alert-success alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
#TempData["SuccessMessage"]
</div>
}
else if (#TempData["ErrorMessage"] != null)
{
<div class="alert alert-danger alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
#TempData["ErrorMessage"]
</div>
}
<div class="spacer"></div>
#RenderBody()
<hr id="hr" />
<footer>
<p>© #DateTime.Now.Year - Your APp </p>
</footer>
</div>
Now, all you need to do inside your controller is:
public class MyController:BaseController
{
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,Name,Email,Phone,Message,Date")] Contact_US contact_US)
{
if (ModelState.IsValid)
{
db.Contact_US.Add(contact_US);
db.SaveChanges();
SucccessMessage = "POSTED SUCESSFULLY...! We WILL CONTACT YOU SOON.";
return RedirectToAction("Index");
}
return View(contact_US);
}
}

how to send a form that contains another form

I have a form that contains another form.
the first form sends data to the action indicated in the beginform which the particular form it contains.
The second form ( contained in the first ) is a list that on change event, exchange a picture, this works .
but the first form is not sent yet.
how can I do to submit the first form normaly and the second with the javascript on change ?
#using (Html.BeginForm("VCreateCommande", "CCommande", new {id="formretouche"}, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
var imagedefaut = "";
#Html.AntiForgeryToken()
<h4>Retouchephoto</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group ilnblk">
<div class="control-label col-md-2 fltleft">Type de retouche</div>
<div class="col-md-10 fltleft">
#using (Html.BeginForm("VCreateCommande", "CCommande", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.DropDownListFor(model => model.Ttyperetouche.Idtyperetouche, new SelectList(
Model.Ttyperetouches, "Idtyperetouche", "libelle", ViewData["Idtyperetouche"]), new { #onchange = "this.form.submit()" })
} </div>
<div class="fltleft imagemodele">
#if (ViewData["Idtyperetouche"] != null)
{
foreach (var typeretouche in Model.Ttyperetouches)
{
if (typeretouche.Idtyperetouche.ToString() == ViewData["Idtyperetouche"].ToString())
{
imagedefaut = typeretouche.SRCtyperetouche;
}
}
}
else
{
imagedefaut = Model.Ttyperetouches.First().SRCtyperetouche;
}
<img src="#imagedefaut" />
</div>
</div>
<div class="form-group">
<div class="control-label col-md-2">Support papier</div>
<div class="col-md-10">
#Html.CheckBoxFor(model => model.Tretouche.Supportpapier, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Tretouche.Supportpapier, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="control-label col-md-2">Quantité</div>
<div class="col-md-10">
#Html.EditorFor(model => model.Tretouche.Quantite, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Tretouche.Quantite, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="control-label col-md-2">Photo...</div>
<div class="col-md-10">
#Html.TextBoxFor(model => model.Tretouche.fichierphoto, new { type = "file" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
#{
String onclick = String.Format("Submit(this)",
Html.Encode(ViewBag.returnUrl));
}
<input type="button" id="btnsubmitretouche" value="Ajouter1" onclick="#onclick" />
<input type="submit" value="Ajouter" class="btn btn-default"/>
</div>
</div>
}
It is not valid html5 to nest forms, see the W3C HTML5 Working Draft.

How do I get Bootstrap file input data to controller in MVC 5

I'm using the Bootstrap File Input plugin to upload an image in my ASP.Net MVC 5 application form. I'm not sure what I need to see on the controller or what I need to do in javascript to get this to work. Currently there is an error that is being thrown when I submit my data in the form that says
"The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters."
Here is my StudentController.
[HttpPost]
public ActionResult Edit(EditStudentViewModel studentViewModel)
{
if (ModelState.IsValid)
{
...other code left out
Here is my javascript
$("#input-20").fileinput({
'type': 'POST',
'cache': false,
'browseClass': 'btn btn-primary btn-block',
'showCaption': false,
'showRemove': false,
'showUpload': false,
'uploadAsync': false,
'maxFileCount': 1,
'allowedFileExtensions': ['jpg', 'png', 'gif'],
'allowedFileTypes': ['image']
'uploadUrl': '#Url.Action("Edit", "Student")'
});
*Are these the correct 'uploadUrl' parameters
Here is my form that submits the data to the controller. You can see I'm submitting what in the ViewModel as well as the image. The byte[] that represents the iamge is in the view model
#model YogaBandy.DomainClasses.ViewModels.Student.EditStudentViewModel
#{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#Html.Partial("_MenuPartial")
<div class="row submenurow">
#Html.Partial("_StudentTeacherProfilePartial")
<div class="col-md-9 submenucol2">
#using (Html.BeginForm("Edit", "Student", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
#Html.HiddenFor(model => model.StudentId)
#Html.HiddenFor(model => model.AspNetUserRefId)
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Student Picture</h3>
</div>
<div class="panel-body">
#Html.TextBoxFor(model => model.TestImage, new { #type = "file", #id = "input-20" })
</div>
</div>
<br/>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Student Profile</h3>
</div>
<div class="panel-body">
<div class="form-group">
#Html.LabelFor(model => model.CatchPhrase, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-sm-10">
#Html.EditorFor(model => model.CatchPhrase, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.CatchPhrase, "", new { #class = "text-danger" })
</div>
</div>
...other form-group's left out below to save space
</div>
</div>
<br />
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
}
</div>
Here is my ViewModel being submitted to the controller
public class EditStudentViewModel
{
public byte[] TestImage { get; set; }
...other values left out
}

Categories