ASP.NET MVC - IHtmlFormElement's GetSubmission returns null - asp.net-mvc

I'm making a POST request through an MVC controller using ASP.NET MVC and while unit testing I'm getting 'Object reference not set to an instance of an Object' from an IHtmlFormElement's GetSubmission() method. The test finds the button and the button itself is not null, but when the test calls the GetSubmission() with the submit button as a parameter it returns null.
Everything works fine from browser.
This is my Add.cshtml file content:
#model MVCPhones.Data.Phone
<form method="post" asp-action="Add">
<div class="form-group">
<label asp-for="Make" class="control-label">Make</label>
<input asp-for="Make" type="text" class="form-control" />
</div>
<div class="form-group">
<label asp-for="Model" class="control-label">Model</label>
<input asp-for="Model" type="text" class="form-control" />
</div>
<div class="form-group">
<label asp-for="RAM" class="control-label">RAM</label>
<input asp-for="RAM" type="number" class="form-control" />
</div>
<div class="form-group">
<label asp-for="PublishDate" class="control-label">PublishDate</label>
<input asp-for="PublishDate" type="date" class="form-control" />
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
Here is my PhonesController post method:
public async Task<IActionResult> Add(Phone phone)
{
try
{
phone.Created = DateTime.Now;
phone.Modified = DateTime.Now;
await _context.Phones.AddAsync(phone);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
catch
{
return View();
}
}
Here is the section that gives the error:
Error

Related

How to get Input control value in controller's Index method asp.net core

I am working on captcha authentication. I want to get user entered captcha value in controller's Index method. Below is my cshtml file code
#{
ViewData["Title"] = "Home Page";
}
<div class="container">
<label for="captcha"><b>Enter chaptcha - </b></label>
<label id="lblshowCaptcha"><b>#ViewData["captcha"]</b></label>
<input id="txtCapValue" type="text" placeholder="Enter captcha" name="cap" required>
<br/>
<button class="button" type="submit">Login</button>
<br />
</div>
When user entering captcha value in txtCapValue and click submit button I need that value in controller. Here is my controller
public IActionResult Index()
{
randnumber = RandomString(6);
ViewData["captcha"] = randnumber;
return View();
}
how can I get txtCapValue input control value when user click on submit button ?
One of the easy ways using the Form Tag Helper:
<form asp-controller="Controller_Name" asp-action="Captcha" method="post">
<div class="container">
<label for="captcha"><b>Enter chaptcha - </b></label>
<label id="lblshowCaptcha"><b>#ViewData["captcha"]</b></label>
<input id="txtCapValue" type="text" placeholder="Enter captcha" name="cap" required>
<br />
<button class="button" type="submit">Login</button>
<br />
</div>
</form>
And on the server side:
[HttpPost]
public IActionResult Captcha(string cap)
{
... using the `cap`
return View("Index");
}
I want to get user entered captcha value in controller's Index
method.
There are two options, you can try:
Option1: use Form Tag Helper
Index method:
public IActionResult Index(string cap)
{
ViewData["captcha"] = 6;//do your staff
return View();
}
Index view:
<form method="get" asp-action="Index">
<div class="container">
<label for="captcha"><b>Enter chaptcha - </b></label>
<label id="lblshowCaptcha"><b>#ViewData["captcha"]</b></label>
<input id="txtCapValue" type="text" placeholder="Enter captcha" name="cap" required>
<br />
<button class="button" type="submit">Login</button>
<br />
</div>
</form>
Option 2: use ajax
Index method:
public IActionResult Index(string cap)
{
ViewData["captcha"] = 6;
return View();
}
Index view:
<div class="container">
<label for="captcha"><b>Enter chaptcha - </b></label>
<label id="lblshowCaptcha"><b>#ViewData["captcha"]</b></label>
<input id="txtCapValue" type="text" placeholder="Enter captcha" name="cap" required>
<br />
<button id="buttonDemo1" class="button" type="submit">Login</button>
<br />
</div>
#section scripts{
<script type="text/javascript">
$(document).ready(function () {
$('#buttonDemo1').click(function () {
var cap = $("#txtCapValue");
$.ajax({
type: 'GET',
url: '/Home/Index',
data: cap
});
});
});
</script>
}
result:

How to load value of last employeeid + 1 in add action

I have controller name emp have action add
i need when action add view loaded display last value increased by one in
employeeid textbox .
meaning suppose i have in employee table employeeid value 1 then when action add
view loaded employeeid must have 2 .
so that how to do that please ?
in action what i write
[httpget]
Hide Copy Code
public IActionResult Create()
{
what i write here
}
on view add
what i write here
<div class="form-group">
<label asp-for="EmployeeId" class="control-label"></label>
<input asp-for="EmployeeId" class="form-control" />
<span asp-validation-for="EmployeeId" class="text-danger"></span>
</div>
What I have tried:
var results = _context.GetAll().Where(Employee => Employee.EmployeeId> Employee.EmployeeId).OrderBy(Employee => Employee.EmployeeId).FirstOrDefault();
and i pass model to view
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="EmployeeId" class="control-label"></label>
<input asp-for="EmployeeId" class="form-control" />
<span asp-validation-for="EmployeeId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="BranchCode" class="control-label"></label>
<input asp-for="BranchCode" class="form-control" />
<span asp-validation-for="BranchCode" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="EmployeeName" class="control-label"></label>
<input asp-for="EmployeeName" class="form-control" />
<span asp-validation-for="EmployeeName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="EmployeeAge" class="control-label"></label>
<input asp-for="EmployeeAge" class="form-control" />
<span asp-validation-for="EmployeeAge" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="JoinDate" class="control-label"></label>
<input asp-for="JoinDate" class="form-control" />
<span asp-validation-for="JoinDate" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="BirthDate" class="control-label"></label>
<input asp-for="BirthDate" class="form-control" />
<span asp-validation-for="BirthDate" class="text-danger"></span>
</div>
<div class="form-group">
<div class="checkbox">
<label>
<input asp-for="Active" /> #Html.DisplayNameFor(model => model.Active)
</label>
</div>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</form>
</div>
</div>
Please don't use .GetAll() , it'll be cause for performance issue. it means you are loading all employee records to the application side, then you are actually querying to loaded employee data. just think about if you have 50K+ employee. So, you have to use LINQ IQueryable extension methods, which will generate the SQL operation based on your design query.
Help Link:.NET Entity Framework - IEnumerable VS. IQueryable
Please Try This, if you want to do some other expressions.
context.Employee.Select(x => x.EmployeeId).DefaultIfEmpty(0).Max()+1
If your model have property EmployeeId then set this value to it like below.
public IActionResult Create()
{
var model = new Employee();
model.EmployeeId = _context.GetAll().Max(Employee => Employee.EmployeeId).FirstOrDefault() + 1;
return View(model);
}
Or if you don't have Model to pass to View then use ViewBag.
ViewBag["maxEmployeeId"] = _context.GetAll().Max(Employee => Employee.EmployeeId).FirstOrDefault() + 1;

Asp.Net MVC - Data permutator

I have searched for hours for this without finding an answer, so I'm asking your help (I'm a beginner in web development (and in Asp.Net MVC)).
I want to create a simple data permutator (for example you enter 3 datas "a, b, and c", and I give you the possible permutations between these 3 datas : "abc; acb; bac; bca; cab; cba").
I have tried the following code, but it does not work (I have an HTTP 404 error).
<form method="post">
<div class="col-md-4 input-group">
<div class="input-group-addon">1</div>
<input type="text" name="firstData" class="form-control" placeholder="First Data" maxlength="50" required />
</div>
<div class="col-md-4 input-group">
<div class="input-group-addon">2</div>
<input type="text" name="secondData" class="form-control" placeholder="Second Data" maxlength="50" required />
</div>
<div class="col-md-4 input-group">
<div class="input-group-addon">3</div>
<input type="text" name="thirdData" class="form-control" placeholder="Third Data" maxlength="50" required />
</div>
<div class="col-md-12 mainAction centerbloc">
<input type="submit" value="Permutate the data" class="btn btn-success register-button-slider" href="">
</div>
</form>
And then below, I want to display the result in the same page, like this :
#{ if (IsPost)
{
string firstdata = Request.Form["firstData"];
string seconddata = Request.Form["secondData"];
string thirddata = Request.Form["thirdData"];
<p>
#firstdata #seconddata #thirddata<br />
#seconddata #firstdata #thirddata<br />
</p>
}
}
I haven't put anything special in my controller (maybe the mistake is here?) :
namespace Blogs.Controllers
{
public class ToolsController : Controller
{
[Route("tools/datapermutator", Name = "DataPermutator"), HttpGet]
public ActionResult DataPermutator()
{
return View();
}
}
}
If you have a way to do it, it would be very helpful, thank you in advance!

Google's new recaptcha not validating

Am I missing something? I copied this code snippet over:
Automatically render the reCAPTCHA widget
I entered my registered data-sitekey. The reCAPTCHA displays and works when I check the box, but if I don't check the box and submit my form, the reCAPTCHA doesn't stop the user submission and my controller processes the request.
#model Medicaid.WebUI.ViewModels.RequestModel
<script src='https://www.google.com/recaptcha/api.js' async defer></script>
<table class="table">
<tr>
<td>
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "request-form", #class = "form-horizontal" }))
{
#Html.AntiForgeryToken()
<fieldset>
<legend>Request</legend>
<div class="form-group">
<label for="inputFirstName" class="col-lg-2 control-label">First Name</label>
<div class="col-lg-10">
<input type="text" value="#Model.FirstName" class="form-control" maxlength="50" name="FirstName" id="FirstName" placeholder="First Name" required>
</div>
</div>
<div class="form-group">
<label for="inputLastName" class="col-lg-2 control-label">Last Name</label>
<div class="col-lg-10">
<input type="text" value="#Model.LastName" class="form-control" maxlength="50" name="LastName" id="LastName" placeholder="Last Name" required>
</div>
</div>
<div class="form-group">
<label for="inputEmail" class="col-lg-2 control-label">Email</label>
<div class="col-lg-10">
<input type="email" value="#Model.Email" class="form-control" maxlength="100" name="Email" id="Email" placeholder="Email" required>
</div>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2"><br /><br />
<div class="g-recaptcha" data-sitekey="IenterMykeyHere"></div><br /><br />
<button type="submit" class="btn btn-primary">Submit Request</button>
</div>
</div>
</fieldset>
}
</td>
</tr>
</table>
<br /><br />
#Html.ValidationSummary()
I was having this issue and re-read the documentation, and worked it out as the following:
function onBegin() {
$("input[type='hidden']").val(grecaptcha.getResponse());
}
You have to add a javascript function to the "onBegin" parameter of the AjaxOptions object from the MVC html helper - that will copy the value of the widget's response to a hidden variable you need to declare inside your form, so the submit button sends it to the controller. Don't forget to add a variable with the same name to the "RequestModel" view model so that the mvc model-binding passes it and you then will be able, in the server, to know if the user has clicked the button or not.
#using (Ajax.BeginForm("NewRecaptchaVerify", "ReCaptcha", new AjaxOptions
{
HttpMethod = "Post",
OnSuccess = "onSuccess",
OnFailure = "onFailure",
OnBegin = "onBegin",
OnComplete = "onComplete"
}))
{
#Html.HiddenFor(m => m.Response)
<div class="g-recaptcha" data-sitekey="your-site-key"></div>
<input type="submit" id="btnSubmit" value="Submit" />
}
(for the record, I am now facing the problem of knowing, in the server, in cases where the widget prompted the user to enter a text input, after clicking the button - whether he/she entered the text or not. Seems to me that in the end I will have no way out other than performing a GET request, in the server, to the widget's api, as they put it in the documentation: https://www.google.com/recaptcha/api/siteverify?secret=your_secret&response=response_string&remoteip=user_ip_address

Get Model back in Post

Is there any way to get information from my model during a result flagged HttpPost if I cannot pass it as a parameter?
[AcceptVerbs(HttpVerbs.Post)]
public FileUploadJsonResult Upload(HttpPostedFileBase file, IwantMyModelToo! )
I can't really get the actual view model to go through the method, though. Any thoughts?
Here is the primary view. (FoldersController)
<hr class="space" />
<div>
<% Html.RenderAction<Controllers.ImagesController>(i => i.Create(Model)); %>
</div>
<hr class="space" />
Here is the partial view (ImagesController, where the Create method resides)
// bunch of fun jQuery for jQuery Form Uploading.
</script>
<div class="span-24 last">
<fieldset>
<legend>Upload Image</legend>
<form id="ajaxUploadForm" action="<%= Url.Action("Upload", "Images")%>" method="post" enctype="multipart/form-data" >
<div>
<label for="file">Select Image</label><br />
<input type="file" name="file" />
</div>
<input id="ajaxUploadButton" type="submit" value="Upload" />
</form>
</fieldset>
</div>
In your code sample there are no properties connected to any model... Here I have added one (Foo) in a hidden form field, and created a class called MyModel.
View
<div class="span-24 last">
<fieldset>
<legend>Upload Image</legend>
<form id="ajaxUploadForm" action="<%= Url.Action("Upload", "Images")%>" method="post" enctype="multipart/form-data" >
<div>
<%= Html.Hidden("Foo", "bar") %>
</div>
<div>
<label for="file">Select Image</label><br />
<input type="file" name="file" />
</div>
<input id="ajaxUploadButton" type="submit" value="Upload" />
</form>
</fieldset>
</div>
Model
public class MyModel
{
public string Foo {get;set;}
}
Controller
public FileUploadJsonResult Upload(HttpPostedFileBase file, MyModel model)
{
//model.Foo should be accessible here
}

Resources