I am currently trying to program a forgot password page where the user enter their username, their email address and a message which will be sent to the administrator of the site.
Want I want is the following:
After the user clicks on the button the username and the email address should be checked if they are associated. (Those values are saved in my database)
I managed to programm everything but I have a problem which I cannot solve.
Everytime the Razor engine renders the page I'll get a NullReferenceException was unhandled by user code.
I know why this is happening but as I said I cannot fix this.
Here is the code:
#model MvcApplication1.ViewModels.ContactAdminViewModel
#using MvcApplication1.Queries
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<script src="#Url.Content("~/Scripts/jquery-1.7.1.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" />
<title>SendMail</title>
</head>
<body>
#using (Html.BeginForm("SendMail", "ContactAdmin", FormMethod.Post))
{
#Html.ValidationSummary(true)
<div>
<p>
#Html.LabelFor(m => m.username, "username")
#Html.EditorFor(m => m.username)
<p>
#Html.ValidationMessageFor(m => m.username)
</p>
</p>
<p>
#Html.LabelFor(m => m.email, "email")
#Html.EditorFor(m => m.email)
<p>
#Html.ValidationMessageFor(m => m.email)
</p>
</p>
<p>
#Html.LabelFor(m => m.message, "Your message")
<p>
#Html.TextAreaFor(m => m.message, new { cols = "35", rows = "10", #style = "resize:none" })
<p>
#Html.ValidationMessageFor(m => m.message)
</p>
</p>
</p>
<p>
<input id="send-mail" type="submit" class="button" value="Send" />
</p>
</div>
<script type="text/javascript">
$(document).ready(function () {
jQuery('#send-mail').click(function () {
#if (#DQL.CheckUsernameAndEmail(Model.username, Model.email))
{
<text>
alert("Your Message will be sent");
</text>
}
else
{
<text>
alert("Your username is not associated with the email adress");
</text>
}
});
});
</script>
}
</body>
</html>
Any tips on how to solve that problem are highly appreciated :)
EDIT
The DQL.cs is a C# Class where I wrote down all my queries.
It's actually the model that is null. I forgot to write that :/ I'm really sorry.
Nevertheless here is the code from the DQL.cs which checks if the username is associated with the email address:
public static bool CheckUsernameAndEmail(string username, string email)
{
bool validateUser = false;
var query = from u in db.User
where (u.email.Equals(email) && u.username.Equals(username))
select u;
if (query.Count() != 0)
validateUser = true;
return validateUser;
}
This the Controller code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcApplication1.ViewModels;
using MvcApplication1.Database_Queries;
namespace MvcApplikation1.Controllers
{
public class ContactAdminController : Controller
{
[HttpGet]
public ActionResult SendMail()
{
return View();
}
[HttpPost]
public ActionResult SendMail(ContactAdminViewModel contactAdmin)
{
if (ModelState.IsValid)
{
if (DQL.CheckUsernameAndEmail(contactAdmin.username, contactAdmin.email))
{
MvcApplication1.Mail.SendMail.SendForgotPassword(contactAdmin.username, contactAdmin.email, contactAdmin.message);
return RedirectToAction("LogIn", "Account");
}
}
else
{
ModelState.AddModelError("", "Your username is not associated with the email adress");
return RedirectToAction("LogIn", "Account");
}
return RedirectToAction("LogIn", "Account");
}
}
}
If this is getting a NullReferenceException:
if (#DQL.CheckUsernameAndEmail(Model.username, Model.email))
Then it's either because DQL is null, Model is null, or some code in CheckUsernameAndEmail is throwing that exception. We don't have enough context in this question to know what DQL is, and the population of your model is done in your controller action, which is not posted in this question. Posting CheckUsernameAndEmail's code may also help.
Basically, any time you get NullReferenceException it means you have a null reference.
Update
Thanks for the updated information! If you don't want your Model to be null when executing your Razor view, make sure to add a model to your ViewResult:
[HttpGet]
public ActionResult SendMail()
{
var model = new ContactAdminViewModel();
// Populate your model with the appropriate data
return View(model);
}
Related
The problem I will be describing is very similar to ones I already found (e.g. this post with nearly identical name) but I hope that I can make it into something that is not a duplicate.
I have created a new ASP.NET MVC 5 application in Visual Studio. Then, I defined two model classes:
public class SearchCriterionModel
{
public string Keyword { get; set; }
}
public class SearchResultModel
{
public int Id { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }
}
Then I created the SearchController as follows:
public class SearchController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult DisplaySearchResults()
{
var model = new List<SearchResultModel>
{
new SearchResultModel { Id=1, FirstName="Peter", Surname="Pan" },
new SearchResultModel { Id=2, FirstName="Jane", Surname="Doe" }
};
return PartialView("SearchResults", model);
}
}
as well as views Index.cshtml (strongly typed with SearchCriterionModel as model and template Edit) and SearchResults.cshtml as a partial view with model of type IEnumerable<SearchResultModel> (template List).
This is the Index view:
#model WebApplication1.Models.SearchCriterionModel
#{
ViewBag.Title = "Index";
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>SearchCriterionModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Keyword, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Keyword, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Keyword, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="button" id="btnDisplaySearchResults" value="Search" onclick="location.href='#Url.Action("DisplaySearchResults", "SearchController")'" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
<div id="searchResults">
</div>
As you can see, I added a div with id="searchResults" below the standard template and edited the button. What I want is to display the partial view SearchResults.cshtml in the div on the bottom, but only after the button is clicked. I have succeeded in showing a partial view there by using #Html.Partial("SearchResults", ViewBag.MyData), but it is rendered when the parent view is loaded for the first time and I set ViewBag.MyData in the Index() method already, which is not what I want.
Summary: On clicking the button, I will obtain some List of SearchResultModel instances (via database access) and then the partial view should be rendered, using this newly obtained data as model. How can I accomplish this? I already seem fail at the first step, that is reacting to the button click with the above code. Right now, I navigate to the URL ~/Search/DisplaySearchResults, but of course there's nothing there and no code-behind method is called.
In traditional ASP.NET I'd just have added a server-side OnClick handler, set the DataSource for a grid and show the grid. But in MVC I already fail with this simple task...
Update: Changing the button to #Html.ActionLink I can finally enter the controller method. But naturally since it returns the partial view, it's displayed as the whole page content. So the question is: How do I tell the partial view to be rendered inside a specific div on the client side?
Change the button to
<button id="search">Search</button>
and add the following script
var url = '#Url.Action("DisplaySearchResults", "Search")';
$('#search').click(function() {
var keyWord = $('#Keyword').val();
$('#searchResults').load(url, { searchText: keyWord });
})
and modify the controller method to accept the search text
public ActionResult DisplaySearchResults(string searchText)
{
var model = // build list based on parameter searchText
return PartialView("SearchResults", model);
}
The jQuery .load method calls your controller method, passing the value of the search text and updates the contents of the <div> with the partial view.
Side note: The use of a <form> tag and #Html.ValidationSummary() and #Html.ValidationMessageFor() are probably not necessary here. Your never returning the Index view so ValidationSummary makes no sense and I assume you want a null search text to return all results, and in any case you do not have any validation attributes for property Keyword so there is nothing to validate.
Edit
Based on OP's comments that SearchCriterionModel will contain multiple properties with validation attributes, then the approach would be to include a submit button and handle the forms .submit() event
<input type="submit" value="Search" />
var url = '#Url.Action("DisplaySearchResults", "Search")';
$('form').submit(function() {
if (!$(this).valid()) {
return false; // prevent the ajax call if validation errors
}
var form = $(this).serialize();
$('#searchResults').load(url, form);
return false; // prevent the default submit action
})
and the controller method would be
public ActionResult DisplaySearchResults(SearchCriterionModel criteria)
{
var model = // build list based on the properties of criteria
return PartialView("SearchResults", model);
}
So here is the controller code.
public IActionResult AddURLTest()
{
return ViewComponent("AddURL");
}
You can load it using JQuery load method.
$(document).ready (function(){
$("#LoadSignIn").click(function(){
$('#UserControl').load("/Home/AddURLTest");
});
});
source code link
I have written this ajax code to send data to web service asmx. It works but with a single click, it inserts data multiple times and sometimes it takes 2,3 click to insert data.
.js
<script type="text/javascript">
function save()
{
$("button").click
(
function()
{
$.post
(
"http://localhost:82/ws/himher.asmx/InsertUsers",
{name: txtUserName.value, pwd: txtUserPwd.value},
//
);
}
);
}
</script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<label>User Name</label>
<input id="txtUserName" type="text" class="form-control" />
</div>
</div>
<div class="row">
<div class="col-md-12">
<label>Password</label>
<input id="txtUserPwd" type="text" class="form-control" />
</div>
</div>
<br/>
<div class="row">
<div class="col-md-12">
<button type="submit" onclick='save()' class="btn btn-primary pull-right">Register</button>
</div>
</div>
</div>
.cs:
public class himher : System.Web.Services.WebService
{
[WebMethod(EnableSession = true)]
//[ScriptMethod(UseHttpGet = false)]
public string InsertUsers(string name, string pwd)
{
try
{
basicoperation bop = new basicoperation();
return bop.insertUsers(name, pwd);
}
catch (Exception ex)
{
throw ex;
}
}
public string insertUsers(string Name, string Password)
{
string status;
String ConStr = ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString;
SqlConnection sqlCon = new SqlConnection(ConStr); // to make a connection with DB
SqlCommand sqlCom = new SqlCommand("InsertUsers", sqlCon); // now in order to perform action such as insert SP, we must create command object which needs command name and conncetion only
sqlCom.CommandType = CommandType.StoredProcedure; // you must tell the system that insertInfo is a storedprocedure
SqlParameter sqlParamName = new SqlParameter("#UserName", Name);
SqlParameter sqlParamPwd= new SqlParameter("#Password", Password);
sqlCom.Parameters.Add(sqlParamName);
sqlCom.Parameters.Add(sqlParamPwd);
try
{
sqlCon.Open();
int i= sqlCom.ExecuteNonQuery(); // executenonquery is used for INSERT, UPDATE, DELETE
//sqlCom.ExecuteScalar(); // used to pick or read a single value from procedure
// Response.Write("Done");
sqlCon.Close();
status= "Success";
}
catch (Exception ex)
{
//response.Write(ex.Message);
status = ex.Message;
}
return status;
}
}
You have two bindings to a saving function, one of them is binded when you click on your button. Rewrite your JS like this:
<script type="text/javascript">
function save()
{
$.post(
"http://localhost:82/ws/himher.asmx/InsertUsers",
{name: txtUserName.value, pwd: txtUserPwd.value}
);
}
</script>
This way your save function will do only saving logic. Binding to call this function is done in HTML by <button type="submit" onclick='save()'>.
If you're going to release this code to users you really need to implement some duplicate action prevention rather than hope they just click it once. Ergo while you may find out why it insets multiples, you cannot rely on user behaviour to keep trash out of the database; they will hit a go slow and hammer that button in frustration. Even if you disable the button, they'll refresh and submit again. Dedupe your data before you insert - this is multi layer information security; even if they disable the script that stops them hammering the button, you don't accept the duplicates
Note, I don't offer this as a solution to a genuine "I click this once and 3 data are inserted" - fix that bug sure, but control the user behaviour with regards to your desire for data purity, within the server (where you're in total control)
Hi all I don't know is this possible or not ,that's why guys I need suggestion to achieve this .The thing is I want to post javacript object with ajax-beginform instead of model object to controller . i code like bellow but cant find a way to post the data ,I know jQuery ajax is an option ,but I don't want to use jQuery ajax for posting data in this case .
HTML
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#section scripts{
<script type="text/javascript">
var getValues=function()
{
//alert(1)
var v = {
id: $("#txtid").val(), name: $("#txtName").val()
}
console.log(v)
return v;
}
</script>
}
<h2>Index</h2>
#using (Ajax.BeginForm("postvalue", new AjaxOptions { HttpMethod="POST", OnBegin = "getValues" }))
{
<input type="text" id="txtid" />
<br />
<input type="text" id="txtName" />
<br />
<button type="submit" value="Click" style="width:50px;height:50px">Click</button>
}
Contoller
namespace AjaxBeginForm.Controllers
{
public class AjaxBeginFormController : Controller
{
// GET: AjaxBeginForm
public ActionResult Index()
{
return View();
}
public void postvalue(searchValues objsearchValues)
{
}
}
public class searchValues
{
public Int64 id { get; set; }
public string name { get; set; }
}
}
I want to post data to controller and catch them in objsearchValues .
Put the JS value in a hidden field in the form and when the form is submitted it will pass the value back to the controller.
I need to perform custom validation in AJAX popup in MVC. I have created a CustomValidator and am overriding the IsValid() method. Problem lies that the popup doesn't render the custom validations properly.
My code:
_Layout.cshtml
<!DOCTYPE html>
<html>
<head>
#Styles.Render("~/Content/css")
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.css" />
#Scripts.Render("~/bundles/jquery")
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.ajax.unobtrusive/3.2.4/jquery.unobtrusive-ajax.min.js"></script>
#Scripts.Render("~/bundles/modernizr")
<script>
$(function () {
$("#modalDialog").dialog({
autoOpen:false,
width: 600,
height: 300,
modal: true
});
$("#opener").click(function () {
$("#modalDialog").dialog("open");
});
});
function OnSuccess(response)
{
$("#modalDialog").text(response);
}
</script>
</head>
Index.cshtml:
#model MvcPopup.Controllers.HomeController.SomeModel
#{ViewBag.Title = "Home Page";}
<p>This is page content !!!</p>
<button id="opener">Open Dialog</button>
<div id="modalDialog" title="Basic Modal Dialog">
<p>This is a basic modal dialog</p>
#using (Ajax.BeginForm("Index", new AjaxOptions { UpdateTargetId = "ID", OnSuccess = "OnSuccess" }))
{
<div>
<fieldset>
<legend>Info</legend>
#Html.LabelFor(m => m.EmailAddress)
#Html.TextBoxFor(m => m.EmailAddress)
#Html.ValidationMessageFor(m => m.EmailAddress)
<input type="submit" value="Submit" />
</fieldset>
</div>
}
</div>
HomeController.cs:
public class HomeController : Controller
{
public class SomeModel
{
[CustomValidator]
[Display(Name = "Email address")]
public string EmailAddress { get; set; }
}
public ActionResult Index()
{
var model = new SomeModel();
return View();
}
[HttpPost]
public ActionResult Index(SomeModel model)
{
if (ModelState.IsValid)
{
return PartialView();
}
return PartialView();
}
CustomValidator.cs:
public class CustomValidator : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value != null)
{
if (value.ToString().Contains("X"))
{
return ValidationResult.Success; ;
}
else
{
return new ValidationResult("Enter an email address with letter X");
}
}
else
{
return new ValidationResult("" + validationContext.DisplayName + " is mandatory.Please enter it.");
}
}
}
I can see that the Custom Validations are fired, but the render on the popup page is little bit crooked. Appears like below:
Now, I don't enter any value in the Email textbox, and click on Submit, I can see my custom validation "Email Address is mandatory. Please enter it." gets fired and is evident on the popup page as below:
I mean, its pretty evident that the custom validation should appear near to the email textbox and things should look like a popup. Please help.
EDIT
Validations appear in the popup page, but the content is somewhat crooked. I mean the content of the parent page too appear on the popup page. Snapshot below. How to get rid of it? Please help.
This is a typical and seen quite some time often. The reason that validation didn't fire is because the content like modal dialog is dynamic which is added/appeared on page later. The form validation has to parse the form again to validate the controls that are added dynamically to the page.
You have setup OnSuccess() so you can use it to parse the form.
function OnSuccess()
{
if($.validator)
{
$.validator.unobtrusive.parse("form");
}
$("#modalDialog").html(response);
}
Visit here for more info.
Note that, this solution assumes that your validation is working fine.
I am trying to check for whether or not a CustomUrl is taken within my application. The problem is that when I click the submit button, nothing happens. I having a very difficult time understanding what I have done wrong.
To clarify: There is no javascript errors, the page does not get submitted. There are no errors anywhere of any sort for me to go on. Also, if I remove [Remote] section from AccountViewModel, so it does not attempt to make the check, the page will submit and it will also record the value in the database. So I'm fairly certain it has something to do with the validation I tried to put in place.
Here is the code:
MembersController.cs
public JsonResult IsCustomUrlInUse(string customUrl)
{
return Json(!UserManager.Users.Any(x => x.CustomUrl == customUrl), JsonRequestBehavior.AllowGet);
}
AccountViewModel.cs
[Required]
[StringLength(20, MinimumLength = 3)]
[Display(Name = "Custom URL")]
[Remote("IsCustomUrlInUse", "Members", ErrorMessage="Custom Url is already in use. Please choose another.")]
public string CustomUrl { get; set; }
Register.cshtml
#model Azularis.System.Events.Models.RegisterViewModel
#{
ViewBag.Title = "Register";
}
<h2>#ViewBag.Title.</h2>
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
#using (Html.BeginForm("Register", "Members", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
<h4>Create a new account.</h4>
<hr />
#Html.ValidationSummary("", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(m => m.CustomUrl, new { #class = "col-md-2 control-label"})
<div class="col-md-10">
#Html.TextBoxFor(m => m.CustomUrl, 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>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
EDIT:
Answering questions in comments:
Network Tab in Developer options is capturing the entry of Custom URL field.
When I remove Remote, the validation for minimum characters kicks in and displays an error. Also, even while Remote is there, the minimum character limit still kicks in.
Example of the network tab: http://postimg.org/image/8e2e1hesx/
I have also removed the bundle in the view, to make sure this is not happening due to duplication, but still the same thing happens.
EDIT 2:
I added a Logging line in the IsCustomUrlInUse method, but it never gets triggered. Can it be that somehow I need to enable json call to the server? As in the MVC is blocking json calls until I enable it in settings somewhere?
EDIT 3:
I managed to produce this error, I'm not sure how as I am not able to replicate it, but maybe this helps:
2015-11-29 13:50:19.4659||System.Web.HttpException (0x80004005): The controller for path '/__browserLink/requestData/c244808430ad49a5afee6a0ecb685cf7' was not found or does not implement IController.
at System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType)
at System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName)
at System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory)
at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state)
at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state)
at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
2015-11-29 13:50:47.0584||System.Web.HttpException (0x80004005): The controller for path '/__browserLink/requestData/c244808430ad49a5afee6a0ecb685cf7' was not found or does not implement IController.
at System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType)
at System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName)
at System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory)
at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state)
at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state)
at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)