I have the following simple view that is used to send invitations out to register for our web-site. This is in an admin-only view and once the email address is filled out the admin can click and send the invite. The code is
@using (Html.BeginForm("Upload", "Tools", FormMethod.Post,
new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
<h2>Invite Users</h2>
<div class="form-group">
@Html.LabelFor(m => m.EmailAddress, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.EmailAddress,
new { @class = "form-control", id = "email" })
@Html.ValidationMessageFor(m => m.EmailAddress)
</div>
</div>
<div class="form-group">
@Html.Label("Access To", new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.DropDownList("Product", new SelectList(
new List<Object> {
new { Text = "D", Value = "D" },
new { Text = "U", Value = "U" },
new { Text = "All", Value = "All" }},
"Value",
"Text"),
new { @class = "form-control", id = "product" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<span class="label label-danger">@ViewBag.FailedMessage</span>
<span class="label label-success">@ViewBag.SuccessMessage</span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="button" value="Invite User" class="btn btn-primary" />
</div>
</div>
}
To post back to the controller on the button click with the selected combo-box selection, I use the following Java Script
<script>
$(function () {
$("input[type=button]").click(function () {
var data_email = $('#email').val();
var data_product = $('#product option:selected').text();
$.ajax({
url: 'Tools/SendInvite',
type: 'POST',
data: { email: data_email, product: data_product },
success: function (result) {
}
});
});
});
</script>
The controller method for this is
[HttpPost]
[AllowAnonymous]
public async Task<ActionResult> SendInvite(
string email, string product)
{
ApplicationUser user = null;
if (ModelState.IsValid)
{
user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
if (user.IsAdmin != null && (bool)user.IsAdmin)
{
string key = String.Empty;
string subMsg = String.Empty;
var accessDB = new AccessHashesDbContext();
switch (product) { /* do stuff */ }
// Send email.
try
{
await Helpers.SendEmailAsync(new List<string>() { email }, null, "my message string");
ViewBag.FailedMessage = String.Empty;
ViewBag.SuccessMessage = String.Format(
"Invitation successfully sent to \"{0}\"",
email);
}
catch (Exception)
{
ViewBag.SuccessMessage = String.Empty;
ViewBag.FailedMessage = String.Format(
"Invitation to \"{0}\" failed",
email);
}
}
}
return View();
}
This code works and sends my email template off to the required recipient. However, I want to notify that the email has been sent or has failed to send via the ViewBag
. This code seems to work, but in the view the ViewBag
is empty and no messages are displayed, what am I doing wrong here?
Thanks for your time.
Edit. by using @yhax's answer below, I have come to the following attempted solution; in my controller I have
[HttpPost]
[AllowAnonymous]
public async Task<ActionResult> SendInvite(string email, string product)
{
ApplicationUser user = null;
string result = "{\"invite_result\":\"{0}\",\"invite_success\":\"{1}\"}";
if (ModelState.IsValid)
{
user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
if (user.IsAdmin != null && (bool)user.IsAdmin)
{
string key = String.Empty;
string subMsg = String.Empty;
var accessDB = new AccessHashesDbContext();
switch (product) { /* do stuff */ }
// Send email.
try
{
await Helpers.SendEmailAsync(new List<string>() { email }, null, "my message string");
result = String.Format(result,
String.Format("Invitation successfully sent to \"{0}\"", email),
"true");
return Content(result);
}
catch (Exception)
{
result = String.Format(result,
String.Format("Invitation to \"{0}\" failed", email),
"false");
return Content(result);
}
}
}
result = String.Format(result, "Invite Failed", "false");
return Content(result);
}
In my JavaScript within my view I now have:
<script>
$(function () {
$("input[type=button]").click(function () {
var data_email = $('#email').val();
var data_product = $('#product option:selected').text();
$.ajax({
url: 'Tools/SendInvite',
type: 'POST',
data: { email: data_email, product: data_product },
success: function (result) {
var obj = JSON.parse(jsontext);
if (obj.invite_success == "true") {
$('#fail_message').val("");
$('#success_message').val(obj.invite_result);
}
else {
$('#fail_message').val(obj.invite_result);
$('#success_message').val("");
}
},
error: function () {
alert("Invite Failure");
}
});
});
});
</script>
This is always hitting the error
condition and shows an alert. When I comment this error: function()
out, then my post does not fire to the controller! What am I doing wrong in this case?
I think you want something like this:
Controller:
[HttpPost]
[AllowAnonymous]
public async Task<ActionResult> SendInvite(
string email, string product)
{
ApplicationUser user = null;
if (ModelState.IsValid)
{
user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
if (user.IsAdmin != null && (bool)user.IsAdmin)
{
string key = String.Empty;
string subMsg = String.Empty;
var accessDB = new AccessHashesDbContext();
switch (product) { /* do stuff */ }
// Send email.
try
{
await Helpers.SendEmailAsync(new List<string>() { email }, null, "my message string");
return Content(String.Format("Invitation successfully sent to \"{0}\"", email));
}
catch (Exception)
{
return Content(String.Format(
"Invitation to \"{0}\" failed",
email));
}
}
}
// you could redirect to another action, or return some other message
return Content("not valid etc etc");
}
and then in here you could do something with the returned message:
<script>
$(function () {
$("input[type=button]").click(function () {
var data_email = $('#email').val();
var data_product = $('#product option:selected').text();
$.ajax({
url: 'Tools/SendInvite',
type: 'POST',
data: { email: data_email, product: data_product },
success: function (result) {
// do something here... show a box with the message, whatever you like
console.log(result);
}
});
});
});