Sending mail with Postal library in MVC 5 - asp.net-mvc-5

I'm using the Postal library to send emails from the contact page. I have the following code:
ContactEmail
using AccessorizeForLess.ViewModels;
using Postal;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace AccessorizeForLess.Models
{
public class ContactEmail : Email
{
public string To { get; set; }
[DataType(DataType.EmailAddress)]
[DisplayName("Email Address")]
[RegularExpression(#"^([\w\.\-]+)#([\w\-]+)((\.(\w){2,3})+)$", ErrorMessage = "The Email field is not valid, Please enter a valid email address!")]
[Required(ErrorMessage="Email address is required.")]
public string From { get; set; }
[DisplayName("First Name")]
[Required(ErrorMessage="Please provide your first name")]
public string FirstName { get; set; }
[DisplayName("Last Name")]
[Required(ErrorMessage="Please provide your last name")]
public string LastName { get; set; }
[DisplayName("Subject")]
[Required(ErrorMessage="Please select a topic")]
public SelectList Subject { get; set; }
public string SelectedSubject { get; set; }
[DisplayName("Message")]
[DataType(DataType.MultilineText)]
[Required(ErrorMessage="PLease provide a message for the email")]
public string Message { get; set; }
public List<EmailSubjectViewModel> Subjects { get; set; }
}
}
EmailSubjectViewModel
namespace AccessorizeForLess.ViewModels
{
public class EmailSubjectViewModel
{
public int Id { get; set; }
public string Subject { get; set; }
}
}
ContactController
public ActionResult Index()
{
List<EmailSubjectViewModel> Subjects = new List<EmailSubjectViewModel>()
{
new EmailSubjectViewModel(){Id=1, Subject="Website Issues"},
new EmailSubjectViewModel(){Id=2, Subject="Order Issue"},
new EmailSubjectViewModel(){Id=3, Subject="Product Question"},
new EmailSubjectViewModel(){Id=4, Subject="Returns Questions"},
new EmailSubjectViewModel(){Id=5, Subject="Other"}
};
ContactEmail email = new ContactEmail()
{
Subjects = Subjects
};
return View(email);
}
public ActionResult Send(ContactEmail email)
{
ContactEmail e = new ContactEmail();
e.From = email.From;
e.FirstName = email.FirstName;
e.LastName = email.LastName;
e.SelectedSubject = email.SelectedSubject;
e.Message = email.Message;
e.Send();
return View();
}
And last but not least my view:
#model AccessorizeForLess.Models.ContactEmail
#{
ViewBag.Title = "Contact";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Contact</h2>
#using (Html.BeginForm("Send", "Contact", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>AccessorizeForLess.net
<img src="~/Content/icon-facebook.png" /></h4>
<div style="color:red;font-weight:bold;">#ViewBag.Message</div>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.FirstName, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.FirstName)
#Html.ValidationMessageFor(model => model.FirstName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LastName, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.LastName)
#Html.ValidationMessageFor(model => model.LastName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.From, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.From)
#Html.ValidationMessageFor(model => model.From)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SelectedSubject, "Category", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.SelectedSubject, new SelectList(Model.Subjects, "Id", "Subject"), "- Please Select -")
#Html.ValidationMessageFor(model => model.SelectedSubject)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Message, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Message, new { #cols = "25", #rows = "55" })
#Html.ValidationMessageFor(model => model.Message)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Send" class="btn btn-default" />
</div>
</div>
</div>
}
Oops almost forgot the section in my web.config
<system.net>
<mailSettings>
<smtp deliveryMethod="Network" from="admin#accessorizeforless.net">
<network host="smtp.gmail.com" port="587" enableSsl="true" defaultCredentials="true" userName="***********#gmail.com" password="**********" />
</smtp>
</mailSettings>
</system.net>
Now when I fill out the form and click send I get the following error:
System.Net.Mail.SmtpException: The SMTP server requires a secure
connection or the client was not authenticated. The server response
was: 5.5.1 Authentication Required.
I thought I was setting the authenticatioon credentials in the web.config?

I had to change defaultCredentials to false in the web.config and all seems to be working right now.

Related

how to update the Identity User?

I'm developing a website in MVC 5 using code first migration. I want to add the custom attributes in default identity to update the users data but I failed to update the AspNetUsers table although I have added migration and update database too but the result is the same. my code is
in applicationUser I have add three more properties.
public class ApplicationUser : IdentityUser
{
public string Name { get; set; }
public string MobileNo { get; set; }
public string Address { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> 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;
}
}
then I updated RegisterViewModel
[Required]
[Display(Name ="Name")]
public string Name { get; set; }
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
[Required]
[Display(Name = "Mobile Number")]
public string MobileNo { get; set; }
[Required]
[Display(Name = "Address")]
public string Address { get; set; }
and Register View is
<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.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.MobileNo, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.MobileNo, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.Address, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.Address, new { #class = "form-control" })
</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>
after adding the migration and update database in console manager I am unable to create the columns in AspNetUsers table and when I use the -Verbose flag then the error message was
"Cannot find the object "AspNetUsers" because it does not exist or you do not have permissions."
I'm unable to understand that how to fix the problem. Please tell me how to deal with that problem. Thanks
Check whether you can actually connect to your database as fail connection might prevent you from updating the database table. I am using this connection string in my code :
<connectionStrings>
<add name="CONNECTIONSTRING_NAME" connectionString="Data Source(local);
Initial Catalog=YOUR_DATABASE_NAME;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>

My datetime picker from my model is not working

The dateTime picker is not showing in the view for me to select a date for my ReturnDate.It wont give me the little arrow to select from a calendar (datetime picker) and it already fills in values. It just shows a textbox that contains : '0001/01/01 12:00:00 AM'
in my model this is my Returndate field:
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? ReturnedDate { get; set; }
my View is:
<div class="form-group">
#Html.LabelFor(model => model.ReturnedDate, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ReturnedDate)
#Html.ValidationMessageFor(model => model.ReturnedDate)
</div>
</div>
using jquery ui this is my new view:
#model FCproject.Models.Purchase
#{
ViewBag.Title = "Create";
}
<script src="~/Scripts/jquery-ui-1.11.4.min.js"></script>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<h4>Purchase</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.ReturnedDate, new { #class = "control-label col-md-2", #id = "datepicker" })
<div class="col-md-10">
#Html.EditorFor(model => model.ReturnedDate)
#Html.ValidationMessageFor(model => model.ReturnedDate)
</div>
</div>
<script>
$(function () {
$("#datepicker").datepicker();
});
</script>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
But it still shows a textbox with no datetime picker.
if you are running on IE that feature doesn't work, chrome works the best on ui's.
But if still gives you problem i'll suggest you use jquery datepicker:
your View (Modified):
<div class="form-group">
#Html.LabelFor(model => model.ReturnedDate, new { #class ="control-label col-md-2", #id = "datepicker" })
<div class="col-md-10">
#Html.EditorFor(model => model.ReturnedDate)
#Html.ValidationMessageFor(model => model.ReturnedDate)
</div>
</div>
<script>
$(function() {
$( "#datepicker" ).datepicker();
});
</script>
OR visit
http://api.jqueryui.com/datepicker/
Dont forget to reference your ui scripts e.g: (Depending on your script version)
<script src="~/Scripts/jquery-ui-1.11.4.min.js"></script>

Foundation 5 Abide validation not working with MVC5

I am trying to hook up Foundation 5 abide validation to my MVC 5 view.When I leave the required fields and try to submit the form,I see all the required fields highlighted in red,but I want to see the error message I added to the C# view model in the Required(ErrorMessage="username is required"]
These are the things I already added
Added these keys to my root level web.config
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
Added the data_abide attribute to the form element
#using (Html.BeginForm("Register", "Account", FormMethod.Post, new { id = "form-user-register", data_abide = "" }))
{
<div class="row">
<div class="small-3 columns">
#Html.DisplayNameFor(m => m.LoginName)<br />
#Html.TextBoxFor(m => m.LoginName, new { id = "register-loginname"})
</div>
</div>
<div class="row">
<div class="small-3 columns">
#Html.DisplayNameFor(m => m.UserPassword)<br />
#Html.TextBoxFor(m => m.UserPassword, new { id = "register-loginpassword" })
</div>
</div>
<div class="row">
<div class="small-3 columns">
#Html.DisplayNameFor(m => m.Email)<br />
#Html.TextBoxFor(m => m.Email, new { id = "register-loginpassword" })
</div>
</div>
<div class="row">
<div class="small-3 columns">
#Html.DisplayNameFor(m => m.FirstName)<br />
#Html.TextBoxFor(m => m.FirstName, new { id = "register-login-firstname" })
</div>
</div>
<div class="row">
<div class="small-3 columns">
#Html.DisplayNameFor(m => m.LastName)<br />
#Html.TextBoxFor(m => m.FirstName, new { id = "register-login-firstname" })
</div>
</div>
<div class="row">
<div class="small-12 columns">
<div class="left">
<input type="submit" class="button radius small right" value="Register" />
</div>
</div>
</div>
}
I made sure that the jquery.validate.unobtrusive.js and jquery.validate.js is added to the _LayoutView.cshtml
This is the C# Viewmodel
public class RegisterViewModel
{
public int AppUserId { get; set; }
[Display(Name="Username")]
[Required(ErrorMessage="Username is required")]
public string LoginName { get; set; }
[Display(Name = "Email")]
[Required(ErrorMessage = "Email is required")]
public string Email { get; set; }
[Display(Name = "FirstName")]
[Required(ErrorMessage = "FirstName is required")]
public string FirstName { get; set; }
[Display(Name = "LastName")]
[Required(ErrorMessage = "LastName is required")]
public string LastName { get; set; }
[Display(Name = "Password")]
[Required(ErrorMessage = "Password is required")]
public string UserPassword { get; set; }
public AddressViewModel Address { get; set; }
}
Still I only the the above screenshot
I figured out what the issue was.This might help someone like me in the future
I was missing couple of things in my _Layout.cshtml and the Register view
1.Missed thi sfrom _Layout view
<script>
$(document).foundation()
</script>
2.Forgot to add the required HTML5 attribute and the html tag that abide validation uses to display the model error
<div class="small-3 columns">
#Html.DisplayNameFor(m => m.LoginName)<br />
#Html.TextBoxFor(m => m.LoginName, new { id = "register-loginname" ,required=""})
<small class="error">Username is required</small>
</div>
And validation worked like a charm

Model being passed in as null

When trying to add a new item to the database (using EF 6.1.3 and MVC 5) my model is always being passed in as null. Here's the model:
using System.ComponentModel.DataAnnotations;
using System.Web;
namespace AccessorizeForLess.ViewModels
{
public class AddNewProductViewModel
{
public string Name { get; set; }
[DataType(DataType.MultilineText)]
public string Description { get; set; }
public decimal Price { get; set; }
public string AltText { get; set; }
public int Quantity { get; set; }
public string ImagePath { get; set; }
public HttpPostedFileBase Image { get; set; }
}
}
Here's the create method in the controller (I know it's convuluted but I'll work on that )
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include="ProductImageId,ProductName,ProductPrice,Quantity,ProductDescription")] AddNewProductViewModel model)
{
ProductImageViewModel image = new ProductImageViewModel() { ImagePath = "/Content/ProductImages/" + model.Image.FileName, AltText = model.AltText };
ProductImage newImage = new ProductImage() { ImagePath = image.ImagePath, AltText = image.AltText };
entities.ProductImages.Add(newImage);
await entities.SaveChangesAsync();
int ImageId = newImage.ProductImageId;
Product product = new Product()
{
ProductImageId = ImageId,
ProductName = model.Name,
ProductDescription = model.Description,
ProductPrice = model.Price,
Quantity = model.Quantity
};
string file = model.Image.FileName;
string path = #"/Content/ProductImages/";
model.Image.SaveAs(path + file);
if (ModelState.IsValid)
{
entities.Products.Add(product);
await entities.SaveChangesAsync();
return RedirectToAction("Index");
}
ViewBag.ProductImageId = new SelectList(entities.ProductImages, "ProductImageId", "ImagePath", product.ProductImageId);
return View("Index");
}
And the view:
#model AccessorizeForLess.ViewModels.AddNewProductViewModel
#{
ViewBag.Title = "Add New Product";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm("Create", "Products", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Product</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.ImagePath, "Image", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.ImagePath, new { #type = "file" })
#Html.ValidationMessageFor(model => model.ImagePath)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.AltText, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.AltText)
#Html.ValidationMessageFor(model => model.AltText)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Name, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Price, new { #class = "control-label col-md-2" ,#width = "25px"})
<div class="col-md-10">
#Html.EditorFor(model => model.Price)
#Html.ValidationMessageFor(model => model.Price)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Quantity, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Quantity)
#Html.ValidationMessageFor(model => model.Quantity)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Description, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Description, new { #cols = "25", #rows = "55" })
#Html.ValidationMessageFor(model => model.Description)
</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>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
What am I doing wrong?
EDIT
#Stephen when I tried to run it again to answer your question I get this
And have no idea what this is, have you seen anything like this before?
EDIT
The error is
Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.
Compiler Error Message: CS1520: Method must have a return type
Source Error:
Line 641: #line default Line 642: #line hidden
Line 643:BeginContext("~/Views/Products/Create.cshtml", 2361, 9,
true); Line 644: Line 645:WriteLiteral("\r\n\r\n");
Source File: c:\Users\Richard\AppData\Local\Temp\Temporary ASP.NET
Files\vs\014a60c5\fc8be8b2\App_Web_create.cshtml.c6727781.vcyi-_hh.0.cs
Line: 643
EDIT
I have this for uploading the image:
string file = model.Image.FileName;
string path = Server.MapPath(#"~/Content/ProductImages");
model.Image.SaveAs(path + "/" + file);
I've stepped through it and all the variables are right, it adds the data to the database but doesn't save the image and I cannot for the life of me figure out why?
Replace:
public async Task<ActionResult> Create([Bind(Include="ProductImageId,ProductName,ProductPrice,Quantity,ProductDescription")] AddNewProductViewModel model)
with:
public async Task<ActionResult> Create([Bind(Include = "ImagePath,AltText,Name,Price,Quantity,Description")] AddNewProductViewModel model)

MVC 5 DataAnnotation Order Attribute

I Can't get the Display -> Order attribute to work.
I'm using VS2013 update 4 and the System.ComponentModel.DataAnnotations appears to be up to date with runtime version 4.0.30319.
I built a tiny MVC app with a small model:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace TestDataAnnotation.Models
{
[MetadataType(typeof(TestDB))]
public class TestDB
{
public int TestDBID { get; set; }
[Display(Order=2)]
public int MyProperty1 { get; set; }
[Display(Order=1)]
public int MyProperty2 { get; set; }
}
}
I created a controller and view using scaffolding. The GET for the Create is standard MVC
// GET: TestDBs/Create
public ActionResult Create()
{
return View();
}
The View is also standard MVC:
<div class="form-horizontal">
<h4>TestDB</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.MyProperty1, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.MyProperty1, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.MyProperty1, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.MyProperty2, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.MyProperty2, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.MyProperty2, "", new { #class = "text-danger" })
</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>
}
MyProperty2 should display first, but it does not. I've tried numerous variations of this but can't get "Order" to work. I've had the MetadataType statement in the code and not in the code. I've tried order= -9. I've tried various different values for the order attribute. Display->Name works fine. Apparently, I'm missing some key idea here. Thanks for any and all help!
The Order parameter applies when there's something dynamic operating on the model and generating HTML, like a grid view. Here, you've literally rendered the properties in a given order. Setting Order isn't going to override explicit HTML.

Resources