JsonResult returns HTML response - asp.net-mvc

I have this method in a controller to reset the password of a user by mail.
public JsonResult RecoverPasswordByEmail(string mail)
{
MembershipUser member = Membership.GetUser(Membership.GetUserNameByEmail(mail));
string newPassword = System.Web.Security.Membership.GeneratePassword(14, 0);
member.UnlockUser();
if (!member.ChangePassword(member.ResetPassword(), newPassword))
{
return Json(new { Resultado = false, Excepcion = "Couldn't change password" }, JsonRequestBehavior.AllowGet);
}
System.Net.Mail.MailAddress from = new System.Net.Mail.MailAddress("foo#bar.com");
System.Net.Mail.MailAddress to = new System.Net.Mail.MailAddress(mail);
System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage(from, to);
message.Subject = "Forgot pass";
if (member.IsLockedOut)
{
message.Body = "You're locked";
}
else
{
message.Body = "New password: " + newPassword;
}
var client = new System.Net.Mail.SmtpClient("my.smtpserver.com", 587)
{
Credentials = new System.Net.NetworkCredential("foo#bar.com", "12345"),
EnableSsl = true
};
try
{
client.Send(message);
}
catch (System.Net.Mail.SmtpException ex)
{
return Json(new { Resultado = false, Excepcion = ex.Message }, JsonRequestBehavior.AllowGet);
}
return Json(new { Resultado = true }, JsonRequestBehavior.AllowGet);
}
I do an ajax request using jQuery from a button in a dialog from the login View.
The weird thing is that I use another controller method RecoverPassword that does the same thing but by the username and that works. Using firebug I see that RecoverPassword does the job and returns a JSON with the result, but RecoverPasswordByEmail responds with a big html document.
The important part of the HTML:
<div id="dialog">
<h2>Retrieve Password</h2>
#Html.Label("Mail:")<br/>
#Html.TextBox("txtMail")
<div id="loading">
<br/><img class="displayed" src="#Url.Content("~/Content/Images/Ajax/ajax-loader3.gif")" alt="loading" /><br/>
#Html.Label("Error")
</div>
<br/><br/><input class="button" id="btnSendMail" type="submit" value="Get new password" />
<div>
Recuperar contraseƱa
</div>
</div>
And the js:
$(document).ready(function () {
var requestMail;
$('#btnSendMail').button();
$('#loading').hide();
$("label[for=Error]").text("");
$('#btnSendMail').click(function (event) {
event.preventDefault();
var mail = $("#txtMail").val();
if (mail.length > 0) {
if (requestMail && requestMail .readystate != 4) {
requestMail .abort();
}
$('#loading').show();
$('input[id="btnSendMail"]').attr('disabled', 'disabled');
requestCorreo = $.ajax({
url: '/Users/RecoverPasswordByEmail',
type: 'POST',
dataType: 'json',
contentType: "application/json; charset=utf-8",
timeout: 8000,
data: { Email: mail },
success: function (response) {
if (response.Result) {
$("label[for=Error]").text('New password has been sent to: ' + mail);
}
else {
alert(response.Result + ' ' + response.Exception);
}
},
error: function (xhr, textStatus, thrownError) {
if (textStatus === "timeout") {
alert("got timeout");
}
else {
alert(xhr.status + ' ' + textStatus + ' ' + thrownError);
}
},
complete: function () {
$('#loading').hide();
$('input[id="btnSendMail"]').removeAttr('disabled');
}
});
}
else {
$("label[for=Error]").text("Insert a valid email");
}
requestCorreo.done(function (msg) {
alert(msg);
});
requestCorreo.fail(function (jqXHR, textStatus) {
alert("Request failed: " + textStatus + " " + jqXHR.responseText);
});
});
});

What is in the HTML that is returned? I'm going to bet that your method is throwing an exception, which is caught by ASP.NET, and an error page is returned rather than the JsonResult from your method.
Or it not, the content of the HTML would help shed more light on the issue.
As a side note, you don't seem to be checking null anywhere in your method - and you're assuming the MembershipUser will be found no matter what email address is passed (which may indeed be the source of your exception).

Related

Devexpress MVC5 Grid GetRowKey(e.visibleIndex) returns always null

Hi everyone I am trying to get the primary key of the selected row to send it to the server later here is the code:
This the mainpage
<script type="text/javascript">
function OnRowClick(s, e) {
var grid = MVCxClientGridView.Cast(s);
var key = grid.GetRowKey(e.visibleIndex);
console.log(key);
$.ajax({
url: '#Url.Action("FundDetails", "Fund")',
type: "POST",
dataType: "text",
traditional: true,
data: { rowKey: key },
success: function (data) {
console.log(data);
},
error: function (xhr, textStatus, errorThrown) {
alert('Request Status: ' + xhr.status + '; Status Text: ' + textStatus +
'; Error: ' + errorThrown);
}
});
}
</script>
<div>
#Html.Partial("_FundsList", Model)
</div>
And this is the partial view that contains the Grid
#Html.DevExpress().GridView(settings =>
{
settings.Name = "FundGrid";
settings.CallbackRouteValues = new { Controller = "Fund", Action =
"FundsList" };
settings.Width = 450;
settings.Columns.Add("codeIsin");
settings.Columns.Add("fundLabel");
settings.Columns.Add("variation");
settings.Columns.Add("ClassNiv1");
settings.SettingsBehavior.AllowSelectByRowClick = true;
settings.SettingsBehavior.AllowSelectSingleRowOnly = true;
settings.ClientSideEvents.RowClick = "OnRowClick";
}).Bind(Model).GetHtml()
the problem is that the key value is always null:
var key = grid.GetRowKey(e.visibleIndex); ==> always Null
PS : e.visibleIndex is not null.
The GetRowKey method explains how null value returned:
If the index passed via the visibleIndex parameter is wrong, or the
ASPxGridBase.KeyFieldName property is not set, null is returned.
It is possible that you need to set KeyFieldName which refers to primary key and/or identity field (with unique value) in the GridView, like this example:
#Html.DevExpress().GridView(settings =>
{
settings.Name = "FundGrid";
settings.CallbackRouteValues = new { Controller = "Fund", Action = "FundsList" };
settings.Width = 450;
settings.Columns.Add("codeIsin");
settings.Columns.Add("fundLabel");
settings.Columns.Add("variation");
settings.Columns.Add("ClassNiv1");
// set primary/identity key field to determine selected row index
settings.KeyFieldName = "codeIsIn";
settings.SettingsBehavior.AllowSelectByRowClick = true;
settings.SettingsBehavior.AllowSelectSingleRowOnly = true;
settings.ClientSideEvents.RowClick = "OnRowClick";
}).Bind(Model).GetHtml()
Also you can put null value checking with if condition before executing AJAX call to ensure key field value passed properly:
var key = grid.GetRowKey(e.visibleIndex);
if (key != null)
{
$.ajax({
url: '#Url.Action("FundDetails", "Fund")',
type: "POST",
data: { rowKey: key },
// other AJAX settings
success: function (data) {
// do something
},
error: function (xhr, textStatus, errorThrown) {
// error handling
}
});
}

render MVC view with json data

I have a method that return json data to my mvc view, not sure why my view shows json data instead of what I have in success part. This is my Post method:
[HttpPost]
[Route("resetpassword")]
public async Task<ActionResult> ResetPassword(ResetPasswordViewModel resetPasswordViewModel)
{
...
if (ModelState.IsValid)
{
if (resetPasswordViewModel.Password == resetPasswordViewModel.ConfirmPassword)
{
var user = Task.Run(() => Service.GetUserByEmailAsync(email)).Result;
if (user != null)
{
userRequest.Id = user.FirstOrDefault().Id;
userRequest.Password = resetPasswordViewModel.Password;
userRequest.Token = token;
await Service.UpdateUserAsync(userRequest);
}
}
else
{
return Json(new { status = "error", message = "Please enter the same value again" });
}
}
return Json(new { status = "success", message = "" });
}
This is my view that is modal:
#model Models.ResetPasswordViewModel
#if (Model != null)
{
<div class="page resetPassword">
#using (Html.BeginForm("resetpassword", "Home", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="modal" id="reset-password">
<div class="modal-content">
<span class="close">X</span>
<div><input type="email" name="email" id="email" readonly value=#Model.Email /></div>
<div class="create-user-label">Password</div>
....
and this is my ajax function:
function resetPassword() {
var postResult = null;
var data = {
Email: document.getElementById('email').value
};
var path = "/resetpassword";
var errorMessage = document.getElementById('Message');
$.ajax({
dataType: "json",
contentType: "text/plain",
url: path,
type: "POST",
cache: false,
data: data,
success: function (result) {
postResult = $.parseJSON(result);
alert(postResult.data);
if (result && result.message) {
$('#reset-password').hide();
$('#reset-thank-you').show();
}
},
error: function () { alert("error"); }
});
}
but instead of my view I only see json data in my screen like:
{"status":"success","message":""}
Your data will be automatically converted from JSON format into Javascript objects.
Presumably you just want to display the message in an alert:
success: function (result)
{
alert(result.data.message);
},
Well your data is going through, looks like you have some mapping problems, you should try this.
$.ajax({
dataType: "json",
contentType: "text/plain",
url: path,
type: "POST",
cache: false,
data: data,
success: function (result) {
alert(result['status']);
if (result['status']== 'success') {
$('#reset-password').hide();
$('#reset-thank-you').show();
}
},
error: function () { alert("error"); }
});

NodeJS and Socket.io session handling

I'm currently trying to set a session (req.session.username) inside a socket.io connection however it will set it but when I refresh and log out the req.session.username, it logs undefined.
I have my socket.io in a router.get callback:
router.get('/', function(req, res, next) {
var io = req.app.get('socketio');
io.sockets.on('connection', function(socket) {
socket.on('login', function(data) {
var username = data.username;
utils.getUser(data.username, function(obj) {
if(typeof obj != 'undefined') {
if(data.password == obj.password) {
req.session.username = username;
socket.emit('loginSuccess', {message: "You have successfully logged in, whats up " + data.username + "?"});
} else {
socket.emit('loginError', {message: "Invalid password, please try again."});
}
} else {
socket.emit('loginError', {message: data.username + " does not exist, please create an account."});
}
});
});
});
console.log(req.session.username);
res.render('./users/login', {
logged: false
});
});

Populating a Webgrid from an Ajax Call

I have a problem with populating a Webgrid from an Ajax call.
I have followed the example as showed in the following thread: mvc3 populating bind webgrid from ajax however, that did not yield any results.
When I run the website, I always get the message: "Error: undefined".
when debugging the code, I am quite sure that the problem lies in the fact that the return PartialView is the problem, as my data object in the ajax success method does not get filled with data.
Here are the examples of my code:
Ajax call:
$.fn.getCardResult = function (leerling, kaart) {
$.ajax({
type: "GET",
url: '#Url.Action("GetResults","Kaarten")',
data: { leerlingID: leerling, cardID: kaart },
cache: false,
success: function (data) {
console.log(data);
if (!data.ok) {
window.alert(' error : ' + data.message);
}
else {
$('#card').html(data);
}
}
});
}
Partial View call:
<div class="card-content" id="card">
#{
if(Model.Kaart != null && Model.Kaart.Count > 0)
{
#Html.Partial("_Kaarten")
}
else
{
#: Er zijn geen kaarten beschikbaar.
}
}
</div>
Partial View:
#model List<ProjectCarrousel.Models.KaartenModel>
#{
var grid = new WebGrid(source: Model,ajaxUpdateContainerId: "card",
defaultSort: "Topicname");
grid.GetHtml(
tableStyle: "webgrid",
columns: grid.Columns(
grid.Column("Topicname", "Topic"),
grid.Column("Taskname", "Taken"),
grid.Column("Taskpoints", "Punten"),
grid.Column("Grades", "Resultaat"),
grid.Column("Date", "Datum"),
grid.Column("Teachercode", "Paraaf Docent")
)
);
}
Controller code:
public ActionResult GetResults(int leerlingID, string cardID)
{
try
{
int Ovnumber = leerlingID;
string CardId = cardID;
List<KaartenModel> kaartlijst = new List<KaartenModel>();
IEnumerable<topic> topics = _db.topic.Include("tasks.studenttotask").Where(i => i.CardID == CardId);
foreach (topic topic in topics)
{
foreach (tasks task in topic.tasks)
{
KaartenModel ka = new KaartenModel();
ka.Topicname = task.topic.Topicname;
ka.Taskname = task.Taskname;
ka.Taskpoints = task.Taskpoints;
ka.Ranks = task.Ranks;
ka.Date = task.studenttotask.Where(i => i.Ovnumber == Ovnumber).Select(d => d.Date).SingleOrDefault();
ka.Grades = task.studenttotask.Where(i => i.Ovnumber == Ovnumber).Select(d => d.Grades).SingleOrDefault();
ka.Teachercode = task.studenttotask.Where(i => i.Ovnumber == Ovnumber).Select(d => d.Teachercode).SingleOrDefault();
kaartlijst.Add(ka);
}
}
KVM.Kaart = kaartlijst;
return PartialView("_Kaarten", KVM.Kaart);
}
catch (Exception ex)
{
return Json(new { ok = false, message = ex.Message });
}
}
If anyone could help it would be greatly appreciated.
UPDATE
After fiddling about a bit I found a solution that worked for me. Below is a snippet of an updated Ajax Call:
The solution I found was too make the Success method in another way. This made sure that the Partial View rendered properly. Below is the Ajax call snippet.
$.ajax({
url: '#Url.Action("GetAjaxCall","Home")',
contentType: 'application/html; charset=utf-8',
type: 'GET',
dataType: 'html',
data: { id: id },
})
.success(function (result) {
$('#sectionContents').html(result);
})
.error(function (xhr, status) {
alert(xhr.responseText);
});
The solution I found was too make the Success method in another way. This made sure that the Partial View rendered properly. Below is the Ajax call snippet.
$.ajax({
url: '#Url.Action("GetAjaxCall","Home")',
contentType: 'application/html; charset=utf-8',
type: 'GET',
dataType: 'html',
data: { id: id },
})
.success(function (result) {
$('#sectionContents').html(result);
})
.error(function (xhr, status) {
alert(xhr.responseText);
});

JQuery UI Multiple Dialogs Not Working

I have a page with two links that open two different modals, the "forgotten password" link opens the "forgotten password" modal and the "tell-a-friend" link opens the "tell-a-friend" modal.
Both modals contain forms that can be submitted.
The problem is if I open the first modal and submit it or close it, I cannot submit the second modal.
I can open the second modal, but I cannot submit it.
Please advise what the problem could be!
Here below is the javascript code that resides in separate javascript file, which is then imported into the HTML file. It is not inline javascript, if that would matter.
[code]
var forgottenPasswordDiv;
var tellAFriendDiv;
function clearErrorMessages() {
$('#errorMessage').text("");
}
function openForgottenPassword() {
forgottenPasswordDiv = $('#forgotten-password');
$('#forgotten-password').load("/Templates/include/new/ajax/modal/forgottenPassword.jsp")
.dialog(
{
autoOpen:false,
modal:true,
position:'left+35% top+20%',
width:'330',
height:'auto'
}
);
$('#forgotten-password').dialog('open');
}
function closeForgottenPassword() {
forgottenPasswordDiv.dialog("close");
}
function submitForgottenPassword() {
clearErrorMessages();
var email = $('#email').val();
if (email == null || email == '') {
$('#errorMessage').text("Please enter your user name or email");
} else {
clearErrorMessages();
/* Ajax Post */
var formData = $("#forgottenPasswordForm").serialize();
$.ajax({
type: "GET",
url: "/Templates/include/new/ajax/forgottenPassword.jsp",
data: formData,
success: function(data) {
if (data.error != null) {
$("#errorMessage").text(data.error);
} else {
$('#forgottenPasswordForm , .info').fadeOut(1000);
$("#successMessage").text(data.success);
$("div").removeClass('display-none');
}
},
dataType: 'json'
});
}
}
function openTellAFriend(gunId) {
tellAFriendDiv = $('#tell-a-friend');
$('#tell-a-friend').load("/Templates/include/new/ajax/modal/tellAFriend.jsp?id=" + gunId)
.dialog(
{
autoOpen:false,
modal:true,
position:'center top+10%',
width:'330',
height:'auto'
}
);
$('#tell-a-friend').dialog('open');
}
function closeTellAFriend() {
tellAFriendDiv.dialog("close");
}
function submitTellAFriend() {
clearErrorMessages();
var yourname = $('#yourname').val();
var errorMessage = "";
if (yourname == null || yourname == '') {
errorMessage += "Please enter your name<br />";
}
if (errorMessage != '') {
$('#errorMessage').html(errorMessage);
} else {
clearErrorMessages();
/* Ajax Post */
var formData = $("#tellAFriendForm").serialize();
$.ajax({
type: "GET",
url: "/Templates/include/new/ajax/tellAFriend.jsp",
data: formData,
success: function(data) {
if (data.error != null) {
$("#errorMessage").text(data.error);
} else {
$("#tellAFriendForm").fadeOut(1000);
$("#successMessage").text(data.success);
$("div").removeClass('display-none');
}
},
dataType: 'json'
});
}
}
[/code]
The ui-dialog widget will stay in the DOM as a hidden element even after the dialog is closed.
So, in order to isolate your two dialog functionalities from each other I'd suggest that you call:
forgottenPasswordDiv.dialog("destroy")
in your "closeForgottenPassword" function and
tellAFriendDiv.dialog("destroy")
in your "closeTellAFriend" function.
This will return the dialog back to its pre-init state (which is not harmful at all because you reinit it in your "open" functions.)

Resources