Uploadify in ASP.NET MVC - c#

I would like to put uploadify in the website I'm making so that I can see the progress of the files that being attach. So I search on how to do that, I know I'm doing something wrong that's why it's not working(the progress doesn't show). Please help me, I'm new with this kind of stuff. Thank you. Here's my controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Index(EmailFormModel model, IEnumerable<HttpPostedFileBase> files)
{
if (ModelState.IsValid)
{
List<string> paths = new List<string>();
foreach (var file in files)
{
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/uploads"), fileName);
file.SaveAs(path);
paths.Add(path);
}
}
var message = new MailMessage();
foreach (var path in paths)
{
var fileInfo = new FileInfo(path);
var memoryStream = new MemoryStream();
using (var stream = fileInfo.OpenRead())
{
stream.CopyTo(memoryStream);
}
memoryStream.Position = 0;
string fileName = fileInfo.Name;
message.Attachments.Add(new Attachment(memoryStream, fileName));
}
//Rest of business logic here
string EncodedResponse = Request.Form["g-Recaptcha-Response"];
bool IsCaptchaValid = (ReCaptcha.Validate(EncodedResponse) == "True" ? true : false);
if (IsCaptchaValid)
{
var body = "<p>Email From: {0} ({1})</p><p>Subject: {2} </p><p>Message:</p><p>{3}</p>";
message.To.Add(new MailAddress("***#gmail.com")); // replace with valid value
message.From = new MailAddress("***#ymailcom"); // replace with valid value
message.Subject = "Your email subject";
message.Body = string.Format(body, model.FromName, model.FromEmail, model.FromSubject, model.Message);
message.IsBodyHtml = true;
using (var smtp = new SmtpClient())
{
var credential = new NetworkCredential
{
UserName = "***#gmail.com", // replace with valid value
Password = "***" // replace with valid value
};
smtp.Credentials = credential;
smtp.Host = "smtp.gmail.com";
smtp.Port = 587;
smtp.EnableSsl = true;
await smtp.SendMailAsync(message);
ViewBag.Message = "Your message has been sent!";
ModelState.Clear();
return View("Index");
}
}
else
{
TempData["recaptcha"] = "Please verify that you are not a robot!";
}
}
return View(model);
}
public ActionResult Upload()
{
var file = Request.Files["Filedata"];
string savePath = Server.MapPath(("~/uploads") + file.FileName);
file.SaveAs(savePath);
return Content(Url.Content(("~/uploads") + file.FileName));
}
And here's the script that I add to my _Layout.cshtml :
<script type="text/javascript" src="#Url.Content("~/Scripts/jquery-1.10.2.min.js")"></script>
<script type="text/javascript" src="#Url.Content("~/Content/UploadifyContent/jquery.uploadify.js")"></script>
<script type="text/javascript" src="#Url.Content("~/Content/UploadifyContent/jquery.uploadify.min.js")"></script>
<link rel="stylesheet" type="text/css" href="#Url.Content("~/Content/UploadifyContent/uploadify.css")" />
<script type="text/javascript">
$(function () {
$('#file_upload').uploadify({
'swf': "#Url.Content("~/Content/UploadifyContent/uploadify.swf")",
'cancelImg': "#Url.Content("~/Content/UploadifyContent/uploadify-cancel.png")",
'uploader': "#Url.Action("Upload", "Home")",
'onUploadSuccess': function (file, data, response) {
$("#uploaded").append("<img src='" + data + "' alt='Uploaded Image' />");
}
});
});
</script>
And here's my view:
#using (Html.BeginForm("Index", "Home", null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="col-md-4">
<div class="contact_form block">
<div class="row">
<div class="col-md-12 col-sm-12">
<div id="note"></div>
</div>
</div>
<div id="fields">
<div class="col-md-12 col-sm-6">
#Html.LabelFor(m => m.FromName)
#Html.TextBoxFor(m => m.FromName, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.FromName, null, new { #class = "text-danger" })
</div>
<div class="col-md-12 col-sm-6">
#Html.LabelFor(m => m.FromEmail)
#Html.TextBoxFor(m => m.FromEmail, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.FromEmail, null, new { #class = "text-danger" })
</div>
<div class="clear"></div>
<div class="col-md-12 col-sm-6">
#Html.LabelFor(m => m.FromSubject)
#Html.TextBoxFor(m => m.FromSubject, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.FromSubject, null, new { #class = "text-danger" })
</div>
<div class="col-md-12 col-sm-6">
<form action="" method="post" enctype="multipart/form-data">
<label for="file1">Attachments</label>
<input type="file" name="files" id="file1" multiple />
</form>
<div id="uploaded"></div>
</div>
<div class="col-md-12">
#Html.LabelFor(m => m.Message)
#Html.TextAreaFor(m => m.Message, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Message, null, new { #class = "text-danger" })
</div>
<div class="col-md-12">
<div>
#if ((TempData["recaptcha"]) != null)
{
<p>#TempData["recaptcha"]</p>
}
</div>
<div class="g-recaptcha" data-sitekey="6LfVHx8TAAAAAMTDxxQrHDCxO1SyXf1GgbgNBZ5a"></div>
</div>
<div class="col-md-12"><input class="shortcode_button" type="submit" value="Send"></div>
</div>
</div>
</div>
}

Related

After I did update-package in the package manager my submit button has lost is functionality and does nothing

I have a registration form and there is two inputs for password and password confirmation. When I enter distinct values I wanted it to show the error message as 'Passwords should match' or something. So I googled it and found out that update-package should fix this problem. Then I applied this solution in order to fix my problem, now, neither my error message shows up nor my submit button works.
My Registration View:
<div class="container-fluid">
#using (Html.BeginForm("Register", "User", FormMethod.Post, new { #class = "col-12" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal p-3 m-3 w-100 d-flex flex-column align-items-center">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group w-100">
<label class="form-control-label col-md-12">Kullanıcı adı</label>
<div class="col-md-12">
#Html.EditorFor(model => model.User.kullaniciAdi, new { htmlAttributes = new { #class = "form-control", #required = "required" } })
#Html.ValidationMessageFor(model => model.User.kullaniciAdi, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Firma adı</label>
<div class="col-md-12">
#Html.EditorFor(model => model.User.firmaAdi, new { htmlAttributes = new { #class = "form-control", #required = "required" } })
#Html.ValidationMessageFor(model => model.User.firmaAdi, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Şifre</label>
<div class="col-md-12">
#Html.EditorFor(model => model.User.sifre, new { htmlAttributes = new { #class = "form-control", #required = "required", #type = "password" } })
#Html.ValidationMessageFor(model => model.User.sifre, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Şifre tekrar</label>
<div class="col-md-12">
#Html.EditorFor(model => model.User.sifreTekrar, new { htmlAttributes = new { #class = "form-control", #required = "required", #type = "password" } })
#Html.ValidationMessageFor(model => model.User.sifre, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">E-mail</label>
<div class="col-md-12">
#Html.EditorFor(model => model.User.mail, new { htmlAttributes = new { #class = "form-control", #required = "required", #type = "text" } })
#Html.ValidationMessageFor(model => model.User.mail, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Telefon</label>
<div class="col-md-12">
#Html.EditorFor(model => model.User.telefon, new { htmlAttributes = new { #class = "form-control", #type = "text", #required = "required" } })
#Html.ValidationMessageFor(model => model.User.telefon, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Ülkeniz</label>
#Html.EditorFor(model => model.Address.ulkeID, new { htmlAttributes = new { #class = "form-control", #type = "text", #readonly="readonly", #Value="Türkiye" } })
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Bulunduğunuz il</label>
<select class="form-control col-md-12" name="Address.sehirID" id="il" required></select>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Bulunduğunuz ilçe</label>
<select class="form-control col-md-12" name="Address.ilceID" id="ilce" disabled required>
<option>Bir İl Seçiniz</option>
</select>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Açık adresiniz</label>
<div class="col-md-12">
#Html.EditorFor(model => model.Address.acikAdres, new { htmlAttributes = new { #class = "form-control", #type = "text", #required = "required" } })
#Html.ValidationMessageFor(model => model.Address.acikAdres, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Oluşturulma Tarihi</label>
<div class="col-md-12">
#Html.EditorFor(model => model.User.olusturulmaTarihi, new { htmlAttributes = new { #class = "form-control", #type = "text", #readonly="readonly", #Value=sqlFormat } })
#Html.ValidationMessageFor(model => model.Address.acikAdres, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<div class="col-md-offset-2 col-md-12">
<input type="submit" value="Kaydol" class="btn btn-success" />
</div>
</div>
</div>
}
</div>
Register Action:
[HttpPost]
public ActionResult Register(RegisterVM model)
{
tblKullanici user = null;
tblAdres address = null;
if(model != null)
{
db = new DatabaseContext();
user = model.User;
address = model.Address;
db.tblKullanici.Add(user);
db.tblAdres.Add(address);
db.SaveChanges();
if (db.SaveChanges() > 0)
{
Session["login"] = model.User;
return RedirectToAction("Index", "App");
}
}
ViewBag.Message = "Kayıt işlemi sırasında hata oluştu!";
return View(model);
}
jQuery
<script>
// ajax call to bring district and city info dynamically according to the city value
$(function () {
$.ajaxSetup({
type: "post",
url: "/User/IlIlce",// target
dataType: "json"
});
$.extend({
ilGetir: function () {
$.ajax({
//sending data
data: { "tip": "ilGetir" },
success: function (sonuc) {
//check result if ok then append it to selectlist
if (sonuc.ok) {
$.each(sonuc.text, function (index, item) {
var optionhtml = '<option value="' + item.Value + '">' + item.Text + '</option>';
$("#il").append(optionhtml);
});
} else {
$.each(sonuc.text, function (index, item) {
var optionhtml = '<option value="' + item.Value + '">' + item.Text + '</option>';
$("#il").append(optionhtml);
$("body").append(optionhtml);
});
}
}
});
},
ilceGetir: function (cityID) {
$.ajax({
// then we get the districts with cityID
data: { "ilID": cityID, "tip": "ilceGetir" },
success: function (sonuc) {
// deleting records
$("#ilce option").remove();
if (sonuc.ok) {
// disabled to false
$("#ilce").prop("disabled", false);
$.each(sonuc.text, function (index, item) {
var optionhtml = '<option value="' + item.Value + '">' + item.Text + '</option>';
$("#ilce").append(optionhtml);
});
} else {
$.each(sonuc.text, function (index, item) {
var optionhtml = '<option value="' + item.Value + '">' + item.Text + '</option>';
$("#ilce").append(optionhtml);
});
}
}
});
}
});
// invoke ilGetir to get city values
$.ilGetir();
// on change in city value
$("#il").on("change", function () {
// we get the id of selected value
var cityID = $(this).val();
// and pass it to the ilceGetir function to get the districts
$.ilceGetir(cityID);
});
});
</script>
and the method that ajax call goes:
public JsonResult IlIlce(int? ilID, string tip)
{
db = new DatabaseContext();
List<SelectListItem> sonuc = new List<SelectListItem>();
bool isSuccessful = true;
try
{
switch (tip)
{
case "ilGetir":
// we assign the city values in db to sonuc(result) variable
foreach (var sehir in db.tblSehir.ToList())
{
sonuc.Add(new SelectListItem
{
Text = sehir.sehirAdi,
Value = sehir.sehirID.ToString()
});
}
break;
case "ilceGetir":
// we will fetch districts with sehirID(cityID)
foreach (var ilce in db.tblİlce.Where(il => il.bagliOlduguSehirID == ilID).ToList())
{
sonuc.Add(new SelectListItem
{
Text = ilce.ilceAdi,
Value = ilce.ilceID.ToString()
});
}
break;
default:
break;
}
}
catch (Exception e)
{
// if we encounter an error
isSuccessful = false;
sonuc = new List<SelectListItem>();
sonuc.Add(new SelectListItem
{
Text = e.Message,
Value = "Default"
});
}
// i return the results as json
return Json(new { ok = isSuccessful, text = sonuc });
}
ilce means: district
sehir/il both means: city
sifre: password
kullaniciAdi: username
telefon: phone number
ulke: country
ilGetir : fetch city
ilceGetir: fetch district
kullanici: user
adres: address
sonuc: result
tip: type

How to call actionresult from the view using button(submit)?

I'm trying to call actionresult in my controller. But it doesn't call it from the view.
I have tried using onclick="location.href='#Url.Action("action", "controller")'"> but it doesn't even enter the function.
My view:
#using (Html.BeginForm("WritePost", "Post", FormMethod.Post, new { enctype
= "Multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Skriv inlägg</h4>
<hr />
<div>
#{Html.RenderAction("_CategoryPartialView", "Category");}
#Html.HiddenFor(model => model.CategoryId)
</div>
<div class="form-group">
#Html.LabelFor(model => model.Title, htmlAttributes: new { #class =
"control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Title, new { htmlAttributes = new {
#class = "form-control" } })
#Html.ValidationMessageFor(model => model.Title, "", new { #class =
"text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Content, htmlAttributes: new { #class =
"control-label col-md-2" })
<div class="col-md-10">
#Html.TextAreaFor(model => model.Content, 10, 100, new { #class =
"form-control" })
#Html.ValidationMessageFor(model => model.Content, "", new { #class =
"text-danger" })
</div>
<input type="file" name="file" />
#Html.ValidationMessageFor(model => model.File)
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Send" class="btn btn-default" />
My Controller
public ActionResult EmailWhenPost()
{
try
{
if (ModelState.IsValid)
{
var senderEmail = new MailAddress("ExampleMail#gmail.com");
var receiverEmail = new MailAddress("ExampleMail2#gmail.com");
var password = "Pass";
var subject = "New Post";
var body = "Message";
var smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(senderEmail.Address, password)
};
using (var mess = new MailMessage(senderEmail, receiverEmail)
{
Subject = subject,
Body = body
})
{
smtp.Send(mess);
}
return View();
}
}
catch (Exception)
{
ViewBag.Error = "Some Error";
}
return View();
}
I want to use the function to send an email when a post is sent. It should not return a view, just trigger the function.
You should call the correct function MyController/EmailWhenPost (please rename this to SendEmail, and add an attribute of [HttpPost] and then in the controller action just return void (a controller method that returns void will produce an EmptyResult.)
First read this article about general rounting in ASP.NET MVC
Then read this msdn article about producing empty results

MVC EF upload image and write to DB at the same time

I am quite new to MVC and coding, so apologies if I don't bring it to the point. I am encountering a weird issue that I somehow cannot manage to solve:
I want to submit a form that includes an image along with other values, such as user name, user ID, timestamp, etc. and write it into a table (SQL); now I can get the image as byte to the DB and I can get the form submitted to the DB, but for some reason I cannot get it done at the same time, so it's either the image/file or the form. The error I encounter is the following:
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.
View Model:
namespace errandomWeb.Models
{
public class PhotoCompetition
{
public int ID { get; set; }
public string UserID { get; set; }
public string FirstName { get; set; }
public string Email { get; set; }
public byte[] CompetitionPicture { get; set; }
//[Required]
[Display(Name = "by checking this box I accept the Terms & Conditions")]
public bool TermsAndConditionsAccepted { get; set; }
public DateTime TimeStamp { get; set; }
}
}
Controller (getting error message):
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult UploadCompetitionPicture(PhotoCompetition model)
{
string croppedImage = Request.Form["photoCompetitionCroppedPicture"];
byte[] imageBytes = Convert.FromBase64String(croppedImage);
var userId = User.Identity.GetUserId();
var participation = new PhotoCompetition
{
CompetitionPicture = imageBytes,
UserID = User.Identity.GetUserId(),
FirstName = "testcase",
Email = User.Identity.GetUserName(),
TermsAndConditionsAccepted = true,
TimeStamp = DateTime.UtcNow.ToUniversalTime(),
};
DB.PhotoCompetition.Add(participation);
DB.SaveChanges();
return View("Edit");
}
}
Controller (working for image, but not the form...):
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult UploadCompetitionPicture()
{
string croppedImage = Request.Form["photoCompetitionCroppedPicture"];
byte[] imageBytes = Convert.FromBase64String(croppedImage);
var userId = User.Identity.GetUserId();
var participation = new PhotoCompetition
{
CompetitionPicture = imageBytes,
UserID = User.Identity.GetUserId(),
FirstName = "testcase",
Email = User.Identity.GetUserName(),
TermsAndConditionsAccepted = true,
TimeStamp = DateTime.UtcNow.ToUniversalTime(),
};
DB.PhotoCompetition.Add(participation);
DB.SaveChanges();
return View("Edit");
}
}
View:
#model errandomWeb.Models.PhotoCompetition
#{
ViewBag.Title = "Become Our Model";
}
<div id="photoCompetitionContainer" class="manageContainer">
<div id="photoCompetitionHeaderSection" class="manageHeaderSection">
<h1 id="photoCompetitionHeaderTitle" class="manageHeaderTitle">
#ViewBag.Title
</h1>
<img id="photoCompetitionHeaderProfilePicture" class="manageHeaderProfilePicture" src="#Url.Action("UserPicture", "Manage")" />
<p id="photoCompetitionHeaderPersonalizationGeneric" class="manageHeaderPersonalization">
Hello
</p>
<p id="photoCompetitionHeaderPersonalizationName" class="manageHeaderPersonalization">
#Html.TextBoxFor(m => m.FirstName, new { #id = "photoCompetitionHeaderUserName", #class = "manageHeaderUserName", #placeholder = "Stranger", #disabled = true })
</p>
</div>
#Html.Partial("_ProfileLogout")
<div id="photoCompetitionContextSection" class="manageContextSection">
<p id="photoCompetitionContext" class="manageContext">
Want to become our model?
</p>
</div>
<div id="photoCompetitionValidationSection" class="manageValidation">
#Html.ValidationSummary("", new { #id = "photoCompetitionValidation", #class = "manageValidation" })
</div>
<section id="photoCompetition" class="manageForm">
#using (Html.BeginForm("UploadCompetitionPicture", "errandom", FormMethod.Post, new { #id = "photoCompetitionForm", #class = "form-horizontal", #role = "form", #enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div id="photoCompetitionSection" class="manageSection">
<p id="photoCompetitionSectionTitle" class="manageSectionTitle">
Upload your picture and be selected as our model!
</p>
#Html.HiddenFor(m => m.UserID)
#Html.HiddenFor(m => m.Email)
#Html.HiddenFor(m => m.FirstName)
#Html.HiddenFor(m => m.TimeStamp)
<div id="photoCompetitionProfilePictureArea" class="manageArea row">
#Html.LabelFor(m => m.CompetitionPicture, new { #id = "photoCompetitionProfilePictureLabel", #class = "manageLabel col-xs-offset-1 col-xs-10 col-sm-offset-1 col-sm-10 col-md-offset-1 col-md-3 col-lg-offset-1 col-lg-4" })
<a id="photoCompetitionProfilePictureSelectionButton" class="manageField col-xs-offset-1 col-xs-10 col-sm-offset-1 col-sm-10 col-md-offset0 col-md-7 col-lg-offset-0 col-lg-6" href="#">
select a file...
</a>
#Html.TextBoxFor(m => m.CompetitionPicture, new { #id = "photoCompetitionProfilePictureField", #class = "manageField col-xs-offset-1 col-xs-10 col-sm-offset-1 col-sm-10 col-md-offset-0 col-md-7 col-lg-offset-0 col-lg-6", #type = "file", #style = "display: none" })
</div>
<div id="photoCompetitionTermsAndConditionsArea" class="manageArea row">
#Html.CheckBoxFor(m => m.TermsAndConditionsAccepted, new { #id = "photoCompetitionTermsAndConditionsField", #class = "photoCompetitionTermsAndConditionsField" })
#Html.LabelFor(m => m.TermsAndConditionsAccepted, new { #id = "photoCompetitionTermsAndConditionsLabel", #class = "photoCompetitionTermsAndConditionsLabel" })
#Html.ValidationMessageFor(m => m.TermsAndConditionsAccepted, "", new { #id = "photoCompetitionTermsAndConditionsValidation", #class = "manageValidation col-xs-offset-1 col-xs-10 col-sm-offset-1 col-sm-10 col-md-offset-4 col-md-7 col-lg-offset-5 col-lg-6" })
</div>
<script>
jQuery("#photoCompetitionProfilePictureSelectionButton").click(function () {
$("#photoCompetitionProfilePictureField").click();
});
</script>
<script>
$("#photoCompetitionProfilePictureField").change(function () {
var fullFileName = $("#photoCompetitionProfilePictureField").val()
$("#photoCompetitionProfilePictureSelectionButton").html(fullFileName.substr(fullFileName.lastIndexOf('\\') + 1));
});
</script>
<div id="photoCompetitionCroppingArea" class="manageArea row">
<img id="photoCompetitionOriginal" class="photoCompetitionImage" src="" alt="" style="display: none" />
<canvas id="photoCompetitionCropped" class="photoCompetitionImage" height="5" width="5"></canvas>
</div>
<div id="photoCompetitionButtonArea" class="manageArea row">
<input id="photoCompetitionButtonCrop" class="manageButton col-xs-offset-1 col-xs-10 col-sm-offset-1 col-sm-10 col-md-offset-1 col-md-10 col-lg-offset-1 col-lg-10" type="button" value="Crop" style="display: none" />
<input id="photoCompetitionButtonUpload" class="manageButton col-xs-offset-1 col-xs-10 col-sm-offset-1 col-sm-10 col-md-offset-1 col-md-10 col-lg-offset-1 col-lg-10" type="submit" value="Save" style="display: none" />
<input id="photoCompetitionCropX" class="photoCompetitionData" name="photoCompetitionCropX" type="hidden" />
<input id="photoCompetitionCropY" class="photoCompetitionData" name="photoCompetitionCropY" type="hidden" />
<input id="photoCompetitionCropW" class="photoCompetitionData" name="photoCompetitionCropW" type="hidden" />
<input id="photoCompetitionCropH" class="photoCompetitionData" name="photoCompetitionCropH" type="hidden" />
<input id="photoCompetitionCroppedPicture" class="photoCompetitionData" name="photoCompetitionCroppedPicture" type="hidden" />
</div>
</div>
}
</section>
<div id="photoCompetitionReturnToMenuSection" class="manageReturnToMenuSection">
#Html.ActionLink("Return to Menu", "Index", "", htmlAttributes: new { #id = "photoCompetitionReturnToMenuButton", #class = "manageReturnToMenuButton" })
</div>
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/tapmodo/Jcrop/master/js/jquery.Jcrop.min.js"></script>
<script type="text/javascript">
$(function () {
if ($('#photoCompetitionCroppingArea').width() > 700) {
$('#photoCompetitionProfilePictureField').change(function () {
$('#photoCompetitionOriginal').hide();
var reader = new FileReader();
reader.onload = function (e) {
$('#photoCompetitionOriginal').show();
$('#photoCompetitionOriginal').attr("src", e.target.result);
$('#photoCompetitionOriginal').Jcrop({
onChange: SetCoordinates,
onSelect: SetCoordinates,
aspectRatio: 1,
boxWidth: 600,
addClass: 'photoCompetitionCropping'
});
}
reader.readAsDataURL($(this)[0].files[0]);
});
}
else {
$('#photoCompetitionProfilePictureField').change(function () {
$('#photoCompetitionOriginal').hide();
var reader = new FileReader();
reader.onload = function (e) {
$('#photoCompetitionOriginal').show();
$('#photoCompetitionOriginal').attr("src", e.target.result);
$('#photoCompetitionOriginal').Jcrop({
onChange: SetCoordinates,
onSelect: SetCoordinates,
aspectRatio: 1,
boxWidth: 250,
addClass: 'photoCompetitionCropping'
});
}
reader.readAsDataURL($(this)[0].files[0]);
});
}
$('#photoCompetitionButtonCrop').click(function () {
var x1 = $('#photoCompetitionCropX').val();
var y1 = $('#photoCompetitionCropY').val();
var height = $('#photoCompetitionCropH').val();
var width = $('#photoCompetitionCropW').val();
var canvas = $("#photoCompetitionCropped")[0];
var context = canvas.getContext('2d');
var img = new Image();
img.onload = function () {
canvas.height = height;
canvas.width = width;
context.drawImage(img, x1, y1, width, height, 0, 0, width, height);
var image = canvas.toDataURL().replace(/^data:image\/[a-z]+;base64,/, "");
$('#photoCompetitionCroppedPicture').val(image);
$('#photoCompetitionButtonUpload').show();
$('#photoCompetitionCropped').hide();
$('#photoCompetitionButtonCrop').hide();
};
img.src = $('#photoCompetitionOriginal').attr("src");
});
});
function SetCoordinates(c) {
$('#photoCompetitionCropX').val(c.x);
$('#photoCompetitionCropY').val(c.y);
$('#photoCompetitionCropW').val(c.w);
$('#photoCompetitionCropH').val(c.h);
$('#photoCompetitionButtonCrop').show();
};
</script>
}
If anyone has an idea on how I could submit the image while also submitting the other properties I would highly appreciate guidance/advice! Thank you!
I finally got it done. Here's the updated controller code:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult UploadCompetitionPicture([Bind(Exclude = "CompetitionPicture")]PhotoCompetition model)
{
string croppedImage = Request.Form["photoCompetitionCroppedPicture"];
byte[] imageBytes = Convert.FromBase64String(croppedImage);
var userId = User.Identity.GetUserId();
var participation = new PhotoCompetition
{
UserID = User.Identity.GetUserId(),
FirstName = "Ken",
Email = User.Identity.GetUserName(),
TermsAndConditionsAccepted = true,
TimeStamp = DateTime.UtcNow.ToUniversalTime(),
};
participation.CompetitionPicture = imageBytes;
DB.PhotoCompetition.Add(participation);
DB.SaveChanges();
return View("Edit");
}
I guess, what made the difference is excluding the picture in the first place, then submitting all other fields and after that adding the picture separately. Not sure why, but glad I figured it out.

wkHtmlToPdf css is not applying when generate the PDF

I have a MVC application and want to generate PDF using HTML. In here I use wkHTMLtoPdf exe to do my job.
I call to an action method from client side using jquery. Then it hit to below method.
public FileContentResult ExportInvoiceASPDF(string invno)
{
try
{
Byte[] bytes;
var fullUrl = this.Url.Action("pdfCustomerInvoice", "Report", new { invNo = invno }, Request.Url.Scheme);
bytes = WKHtmlToPdf(fullUrl);
FileContentResult result = new FileContentResult(bytes, "application/pdf")
{
FileDownloadName = "PriceNotification"
};
return File(result.FileContents, "application/pdf");
}
catch (Exception ex)
{
throw;
}
}
In here I called to WKHtmlToPdf function for getting byte stream. (Below code extracted from stackoverflow thread)
public byte[] WKHtmlToPdf(string url_input)
{
try
{
var fileName = " - ";
var wkhtmlDir = ConfigurationSettings.AppSettings["wkhtmlDir"];//Directory of wkHtmltopdf exe
var wkhtml = ConfigurationSettings.AppSettings["wkhtml"];//wkhtmltopdf exe location
var p = new Process();
url = url_input;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = wkhtml;
p.StartInfo.WorkingDirectory = wkhtmlDir;
string switches = "";
switches += "--print-media-type ";
switches += "--margin-top 10mm --margin-bottom 10mm --margin-right 10mm --margin-left 10mm ";
switches += "--page-size Letter ";
p.StartInfo.Arguments = switches + " " + url + " " + fileName;
p.Start();
//read output
byte[] buffer = new byte[32768];
byte[] file;
using (var ms = new MemoryStream())
{
while (true)
{
int read = p.StandardOutput.BaseStream.Read(buffer, 0, buffer.Length);
if (read <= 0)
{
break;
}
ms.Write(buffer, 0, read);
}
file = ms.ToArray();
}
// wait or exit
p.WaitForExit(60000);
// read the exit code, close process
int returnCode = p.ExitCode;
p.Close();
return returnCode == 0 ? file : null;
}
catch (Exception ex)
{
// set your exceptions here
return null;
}
}
Here I execute the view. (the page which I want to export as PDF)
public ActionResult pdfCustomerInvoice(string invNo)
{
var inv = _customerInvoiceService.GetCustomerInvoice(invNo);
InvoiceSummaryReportsVM invRepVM = new InvoiceSummaryReportsVM();
//My data assigning part going here
return View(invRepVM);
}
Here is pdfCustomerInvoice html.
#model Pro.Web.Models.ViewModels.InvoiceSummaryReportsVM
#{
Layout = null;
}
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
<div class="center">
<h2>Tax Invoice</h2>
</div>
<div class="row">
<br />
<br />
<br />
<br />
<br />
</div>
<div class="row">
<div class="col-md-6">
</div>
<div class="col-md-6">
<div class="row">
<div class="col-md-3">
#Html.LabelFor(model => model.InvoiceNo, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-3">
#Html.DisplayFor(model => model.InvoiceNo, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="row">
<div class="col-md-3">
#Html.LabelFor(model => model.InvoiceDate, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-3">
#Html.DisplayFor(model => model.InvoiceDate, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="row">
<div class="col-md-3">
#Html.LabelFor(model => model.AccountNo, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-3">
#Html.DisplayFor(model => model.AccountNo, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="row">
<div class="col-md-3">
#Html.LabelFor(model => model.InvoiceStatementPeriod, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-3">
#Html.DisplayFor(model => model.InvoiceStatementPeriod, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
#Html.LabelFor(model => model.OpeningBalance, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-6">
#Html.DisplayFor(model => model.OpeningBalance, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="row">
<div class="col-md-6">
#Html.LabelFor(model => model.InvoiceTotal, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-6">
#Html.DisplayFor(model => model.InvoiceTotal, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="row">
<div class="col-md-6">
#Html.LabelFor(model => model.TaxAmount, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-6">
#Html.DisplayFor(model => model.TaxAmount, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="row">
<div class="col-md-6">
#Html.LabelFor(model => model.TotalAmountPayable, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-6">
#Html.DisplayFor(model => model.TotalAmountPayable, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
</body>
</html>
The issue is when I execute the code, it is generated the PDF without styling. (All data align to left side.)
But when I call to "pdfCustomerInvoice" method directly, the html comes properly with styling.
In here I have styling issue. Please give me a direction for fixing this problem.
It seems that bootstrap won't load then.
Try to link bootstrap css from your file system.
For details: https://stackoverflow.com/a/20357784/6589639

Attach Multiple Files in ASP.NET MVC

I've been trying to attach/upload multiple files in the website I'm making. The Name, Email, Subject & Message are sending but there's no attachment in the message. It seems that the files don't get in the uploads folder. I really don't know what's wrong. Please help me. I'm new with this kind of stuff. Thank you. Here's my view:
#using (Html.BeginForm("Index", "Home", null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="col-md-4">
<div class="contact_form block">
<div class="row">
<div class="col-md-12 col-sm-12">
<div id="note"></div>
</div>
</div>
<div id="fields">
<div class="col-md-12 col-sm-6">
#Html.LabelFor(m => m.FromName)
#Html.TextBoxFor(m => m.FromName, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.FromName)
</div>
<div class="col-md-12 col-sm-6">
#Html.LabelFor(m => m.FromEmail)
#Html.TextBoxFor(m => m.FromEmail, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.FromEmail)
</div>
<div class="clear"></div>
<div class="col-md-12 col-sm-6">
#Html.LabelFor(m => m.FromSubject)
#Html.TextBoxFor(m => m.FromSubject, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.FromSubject)
</div>
<div class="col-md-12">
#using (Html.BeginForm("Multiple", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div id="multiple">
<input type="file" class="multiple" name="files" multiple />
</div>
<div id="single">
<input type="file" class="single" name="files" /><br />
<input type="file" class="single" name="files" /><br />
<input type="file" class="single" name="files" /><br />
</div>
}
</div>
<div class="col-md-12">
#Html.LabelFor(m => m.Message)
#Html.TextAreaFor(m => m.Message, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Message)
</div>
<div class="col-md-12">
<div>
#if ((TempData["recaptcha"]) != null)
{
<p>#TempData["recaptcha"]</p>
}
</div>
<div class="g-recaptcha" data-sitekey="6LfVHx8TAAAAAMTDxxQrHDCxO1SyXf1GgbgNBZ5a"></div>
</div>
<div class="col-md-12"><input class="shortcode_button" type="submit" value="Send"></div>
</div>
</div>
</div>
}
And here's my controller:
public ActionResult Index()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Index(EmailFormModel model)
{
if (ModelState.IsValid)
{
string EncodedResponse = Request.Form["g-Recaptcha-Response"];
bool IsCaptchaValid = (ReCaptcha.Validate(EncodedResponse) == "True" ? true : false);
if(IsCaptchaValid)
{
var body = "<p>Email From: {0} ({1})</p><p>Message:</p><p>{2}</p>";
var message = new MailMessage();
message.To.Add(new MailAddress("***#gmail.com")); // replace with valid value
message.From = new MailAddress("***#ymailcom"); // replace with valid value
message.Subject = "Your email subject";
message.Body = string.Format(body, model.FromName, model.FromEmail, model.FromSubject, model.Message);
message.IsBodyHtml = true;
using (var smtp = new SmtpClient())
{
var credential = new NetworkCredential
{
UserName = "***#gmail.com", // replace with valid value
Password = "***" // replace with valid value
};
smtp.Credentials = credential;
smtp.Host = "smtp.gmail.com";
smtp.Port = 587;
smtp.EnableSsl = true;
await smtp.SendMailAsync(message);
//return RedirectToAction("Sent");
ViewBag.Message = "Your message has been sent!";
//TempData["message"] = "Message sent";
ModelState.Clear();
return View("Index");
}
}else
{
TempData["recaptcha"] = "Please verify that you are not a robot!";
}
}
return View(model);
}
[HttpPost]
public ActionResult Multiple(IEnumerable<HttpPostedFileBase> files)
{
foreach (var file in files)
{
if (file != null && file.ContentLength > 0)
{
file.SaveAs(Path.Combine(Server.MapPath("/uploads"), Guid.NewGuid() + Path.GetExtension(file.FileName)));
}
}
return View();
}
Your first row of code is the problem.
Html.BeginForm("Index", "Home", null, FormMethod.Post, new { enctype = "multipart/form-data"
That is a Post action to Index of your home controller. It is not possible to HttpPost another HttpPost, the action itself is expecting an HttpPost, as you can see by the data annotation above the ActionResult name
Why do you use nested forms?
Your view should not be contained nested form submissions. so reduce it to one and the same can be use to upload files.
#using (Html.BeginForm("Index", "Home", null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="col-md-4">
<div class="contact_form block">
<div class="row">
<div class="col-md-12 col-sm-12">
<div id="note"></div>
</div>
</div>
<div id="fields">
<div class="col-md-12 col-sm-6">
#Html.LabelFor(m => m.FromName)
#Html.TextBoxFor(m => m.FromName, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.FromName)
</div>
<div class="col-md-12 col-sm-6">
#Html.LabelFor(m => m.FromEmail)
#Html.TextBoxFor(m => m.FromEmail, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.FromEmail)
</div>
<div class="clear"></div>
<div class="col-md-12 col-sm-6">
#Html.LabelFor(m => m.FromSubject)
#Html.TextBoxFor(m => m.FromSubject, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.FromSubject)
</div>
<div class="col-md-12">
{
<div id="multiple">
<input type="file" class="multiple" name="files" multiple />
</div>
<div id="single">
<input type="file" class="single" name="files" /><br />
<input type="file" class="single" name="files" /><br />
<input type="file" class="single" name="files" /><br />
</div>
</div>
<div class="col-md-12">
#Html.LabelFor(m => m.Message)
#Html.TextAreaFor(m => m.Message, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Message)
</div>
<div class="col-md-12">
<div>
#if ((TempData["recaptcha"]) != null)
{
<p>#TempData["recaptcha"]</p>
}
</div>
<div class="g-recaptcha" data-sitekey="6LfVHx8TAAAAAMTDxxQrHDCxO1SyXf1GgbgNBZ5a"></div>
</div>
<div class="col-md-12"><input class="shortcode_button" type="submit" value="Send"></div>
</div>
</div>
</div>
}
Moreever add a parameter to Action to receive files from client request and process it at same action.
public async Task<ActionResult> Index(EmailFormModel model, IEnumerable<HttpPostedFileBase> files)
{
if (ModelState.IsValid)
{
//logic here upload file logic here.
foreach (var file in files)
{
if (file != null && file.ContentLength > 0)
{
file.SaveAs(Path.Combine(Server.MapPath("/uploads"), Guid.NewGuid() + Path.GetExtension(file.FileName)));
}
}
//Rest of business logic here
string EncodedResponse = Request.Form["g-Recaptcha-Response"];
bool IsCaptchaValid = (ReCaptcha.Validate(EncodedResponse) == "True" ? true : false);
if(IsCaptchaValid)
{
var body = "<p>Email From: {0} ({1})</p><p>Message:</p><p>{2}</p>";
var message = new MailMessage();
message.To.Add(new MailAddress("***#gmail.com")); // replace with valid value
message.From = new MailAddress("***#ymailcom"); // replace with valid value
message.Subject = "Your email subject";
message.Body = string.Format(body, model.FromName, model.FromEmail, model.FromSubject, model.Message);
message.IsBodyHtml = true;
using (var smtp = new SmtpClient())
{
var credential = new NetworkCredential
{
UserName = "***#gmail.com", // replace with valid value
Password = "***" // replace with valid value
};
smtp.Credentials = credential;
smtp.Host = "smtp.gmail.com";
smtp.Port = 587;
smtp.EnableSsl = true;
await smtp.SendMailAsync(message);
//return RedirectToAction("Sent");
ViewBag.Message = "Your message has been sent!";
//TempData["message"] = "Message sent";
ModelState.Clear();
return View("Index");
}
}else
{
TempData["recaptcha"] = "Please verify that you are not a robot!";
}
}
return View(model);
}

Categories

Resources