Getting Null when sending form data from view to controller - c#

i have created this section in my index view
<section id="contact" class="contact">
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="section-title text-center">
<h3>Contact With Us</h3>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<form action="/Home/Contact" method="post" name="sentMessage" id="contactForm" novalidate>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<input type="text" runat="server" class="form-control" placeholder="Your Name *" id="name" required data-validation-required-message="Please enter your name.">
<p class="help-block text-danger"></p>
</div>
<div class="form-group">
<input type="email" runat="server" class="form-control" placeholder="Your Email *" id="email" required data-validation-required-message="Please enter your email address.">
<p class="help-block text-danger"></p>
</div>
<div class="form-group">
<input type="tel" runat="server" class="form-control" placeholder="Your Phone *" id="phone" required data-validation-required-message="Please enter your phone number.">
<p class="help-block text-danger"></p>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<textarea runat="server" class="form-control" placeholder="Your Message *" id="message" required data-validation-required-message="Please enter a message."></textarea>
<p class="help-block text-danger"></p>
</div>
</div>
<div class="clearfix"></div>
<div class="col-lg-12 text-center">
<div id="success"></div>
<button type="submit" class="btn btn-success">Send </button>
</div>
</div>
</form>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="footer-contact-info">
<h4>Action Suraksha Pvt Ltd, Sadhu Petrol Pump, Siwan, Bihar-841226</h4>
<ul>
<li><strong>E-mail :</strong> info#actionsuraksha.com</li>
<li><strong>Phone :</strong> +91-9060611786</li>
<li><strong>Mobile :</strong> +8801-45565378</li>
</ul>
</div>
</div>
<div class="col-md-4 col-md-offset-4">
<div class="footer-contact-info">
<h4>Working Hours</h4>
<ul>
<li><strong>Mon-Sat :</strong> 9 am to 6 pm</li>
<li><strong>Sunday :</strong> Closed</li>
</ul>
</div>
</div>
</div>
</div>
</section>
And i am trying to retrieve this Form value in controller like:
[HttpPost]
public ActionResult Contact()
{
string sURL;
string strname = Request["name"];
string strEmail = Request["email"];
string strPhone = Request["phone"];
string strMessage = Request["message"];
return View();
}
I am getting null value for strname ,strEmail ,strPhone ,strMessage
Please someone help me to solve this issue , thanks in advance.
and if possible give me some example from which i can solve this issue

Your problem is that you don't have any name attributes on your inputs. Only the values of elements with a name attribute will be posted back to the server and the name used is what you look for in the request.
Since you're using MVC, you should look into how view models and Razor work.
runat="server" is not necessary in MVC. That's old-school ASP.NET not MVC.

Create a model to hold the desired data
public class ContactModel {
public string name { get; set; }
public string email { get; set; }
public string phone { get; set; }
public string message { get; set; }
}
Make sure the properties match the input names used in the view.
And update action to accept the posted form data
[HttpPost]
public ActionResult Contact(ContactModel model) {
string sURL;
string strname = model.name;
string strEmail = model.email;
string strPhone = model.phone;
string strMessage = model.message;
//...
return View();
}
The model binder will match the submitted inputs and populate the model parameter before passing it to the action.

You are getting empty form because you don't set up attribute 'name' for input. For example edit your fist input on this way:
<input type="text" runat="server" class="form-control" placeholder="Your Name *" id="name" name="name" required data-validation-required-message="Please enter your name.">
After that you'll get your value from Request:
string strname = Request["name"];
But, I'd recommend you to use ViewModel class for your request. Also, have a look at the documentation (https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/controller-methods-views?view=aspnetcore-2.1)

Related

Data annotation validation happening on page load in ASP.Net Core

I am facing the issue of data validation being executed on load of a new page even though it is clearly coming from a Get method. Is there something that's triggering the validations on page load?
I have a button on a view to add a new Student record in the new screen :
View :
<a type="button" id="btnAddStudent" href='#Url.Action("Details","Student")' class="btn btn-tertiary" title="Add Student">Add Student</a>
The controller code for the Details action method in Student Controller is as follows.
[HttpGet]
public ActionResult Details(StudentInfo model)
{
//This is populating the model parameters as expected.
helper.StudentInfo(ref model);
return View(model);
}
The view for the Details screen is as follows. The page loads but is throwing validation errors even though it's a Get method.
<form id="frmSubmit" asp-action="Details" asp-controller="Student" method="post">
<input type="hidden" asp-for="StudentId" />
<div class="row">
<div class="col-xs-12">
#Html.ValidationSummary("", new { #class = "alert alert-danger validation" })
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label asp-for="Name">*StudentName</label><br />
<input asp-for="Name" class="form-control" maxlength="100" placeholder="Enter student name..." />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label asp-for="AddressLine1"></label><br />
<input asp-for="AddressLine1" class="form-control" placeholder="Enter address..." />
<span asp-validation-for="AddressLine1" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label asp-for="AddressLine2"></label><br />
<input asp-for="AddressLine2" class="form-control" maxlength="100" />
<span asp-validation-for="AddressLine2" class="text-danger"></span>
</div>
</div>
</div>
<div class="box">
<div class="form-group pull-right">
<button type="submit" class="btn btn-primary" value="save"> Save</button>
</div>
</div>
Is there something I am doing wrong? I have verified that the debug control goes to the Get method.There's alos no on load scripts which are doing any sort of validation.
1.Your get method contains the model parameter, when the request hit the method it will judge the ModelState by default. And when you hit the get method by your shared <a>, it send request without any data, so the ModelState is invalid.
2.Default Tag helper displays ModelState's value not Model.
In conclusion, you will render the ModelState error although it is a get method.
Two ways you can resolve this problem. The first way is that you can add ModelState.Clear() before you return View:
public ActionResult Details(StudentInfo model)
{
ModelState.Clear(); //add this....
helper.StudentInfo(ref model);
return View(model);
}
The second way is do not add the model as parameter:
public ActionResult Details()
{
var model = new StudentInfo();
helper.StudentInfo(ref model);
return View(model);
}

ASP.NET Core 6.0 MVC : how to save MultiLine TextBox Text (Value) to database as new records for each new line

As the title says, I am wondering how I would go about parsing out multiple lines of text from a single TextBox, but submit each of those values individually to my database.
The users have a display where they enter in a barcode that represents a physical location at the facility, and they can put multiple plants in that location. So instead of having them submit a new form for every single plant, I figured this would be an easier way to do so.
However, I'm struggling to understand HOW to make this happen in my controller on the HttpPost event for Create();
The info that gets passed is: ID, UserId, PlantId, Barcode, Date, and Time. The ID (auto updated) and PlantId would be the only things that change. The Barcode, Date and Time should be the same value. I have removed all my failed attempts in my examples here so you can see how it works WITHOUT what I'm wanting to do.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,PlantId,Barcode,UserId,Date,Time")] VegLocationModel vegLocationModel)
{
if (ModelState.IsValid)
{
_context.Add(vegLocationModel);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Create));
}
return View(vegLocationModel);
}
View:
#model tester.Models.VegLocationModel
#{
ViewData["Title"] = "Create";
var userName = "TEST";
var currentDate = DateTime.Now.Date.Month.ToString() + "/" + DateTime.Now.Date.Day.ToString() + "/" + DateTime.Now.Date.Year.ToString();
var currentTime = string.Format("{0:hh:mm:ss tt}", DateTime.Now);
Html.Hidden("UserId");
Html.Hidden("Date");
Html.Hidden("Time");
}
<h1>Create</h1>
<h4>VegLocationModel</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Barcode" class="control-label"></label>
<input asp-for="Barcode" class="form-control" style="min-width:100%"/>
<span asp-validation-for="Barcode" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PlantId" class="control-label"></label>
<textarea asp-for="PlantId" class="form-control" rows="10" cols="50">
</textarea>
<span asp-validation-for="PlantId" class="text-danger"></span>
</div>
<div class="form-group">
<input id="UserId" type="hidden" value="#userName" asp-for="UserId" class="form-control" />
<span asp-validation-for="UserId" class="text-danger"></span>
</div>
<div class="form-group">
<input id="Date" type="hidden" value="#currentDate" asp-for="Date" class="form-control" />
<span asp-validation-for="Date" class="text-danger"></span>
</div>
<div class="form-group">
<input id="Time" type="hidden" value="#currentTime" asp-for="Time" class="form-control" />
<span asp-validation-for="Time" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
the value of your textarea posted to Action "Create" is in type of string not int,so you couldn't bind it with VegLocationModel
you could try as below:
[HttpPost]
public IActionResult Create(SomeTest someTest,string plantid)
{
List<int> plantids = plantid.Split("\r\n").Select(m=>Convert.ToInt32(m)).ToList();
return Ok();
}
the result:
try as below to update your database:
public async Task<IActionResult> Create(SomeTest someTest)
{
List<string> plantids = someTest.PlantId.Split("\r\n").ToList();
var soemtestlist = new List<SomeTest>();
foreach (var id in plantids)
{
soemtestlist.Add(
new SomeTest(){
Barcode= someTest.Barcode,
Time= someTest.Time,
UserId= someTest.UserId,
PlantId = id
});
}
_context.SomeTest.AddRange(soemtestlist);
await _context.SaveChangesAsync();
return Ok();
}
The Result:
In the multiline textbox, the new line can be separated as \r\n (works in windows) OR \n\r depending on the operating system. So, logic is simple. Just split your multiline textbox with either \n\r or \r\n and store it in separate rows in the database.

How to pass variable json string into application or session variable using c#?

<form>
<div class="container">
<div class="row">
<div class="col-xs-3 col-lg-2">
SELECT bank name
</div>
<div class="col-xs-3 col-lg-3">
<input id="Text1" type="text" class="form-control" />
</div>
</div>
<div class="row">
<div class="col-xs-3 col-lg-2">
father name
</div>
<div class="col-xs-3 col-lg-3">
<input id="Text1" type="text" class="form-control" />
</div>
<div class="col-xs-3 col-lg-2">
father pan no
</div>
<div class="col-xs-3 col-lg-3">
<input id="Text1" type="text" class="form-control" />
</div>
</div>
<div class="row">
<div class="col-xs-3 col-lg-2">
mother name
</div>
<div class="col-xs-3 col-lg-3">
<input id="Text1" type="text" class="form-control" />
</div>
<div class="col-xs-3 col-lg-2">
mother pan no
</div>
<div class="col-xs-3 col-lg-3">
<input id="Text1" type="text" class="form-control" />
</div>
</div>
<div class="row">
<div class="col-xs-3 col-lg-2">
Account numbers
</div>
<div class="col-xs-3 col-md-6 col-lg-6">
<textarea class="form-control" rows="5" id="fno"></textarea>
</div>
</div>
<div class="row">
<div class="col-xs-3">
<input type="button" runat="server" value="Generate Ffile" id="file" onclick="submit_file_Click();" />
</div>
</div>
</form>
var accountNum;
var bank_name;
var bank;
var fn;
var fpan;
var mn;
var mpan;
var jsonObj = [];
var customerString;
var accString;
$(document).ready(function() {
$("#file").on("click", function() {
customerdetails(amc_name);
accountDetails();
});
});
function customerdetails(amc_name) {
jsonObj = [];
bank = bank_name;
fn = $("#fname").val();;
fpan = $("#pan1").val();;
mn = $("#mname").val();;
mpan = $("#mpan2").val();;
item = {}
item["BANKName"] = bank;
item["F_Name"] = fn;
item["F_PAN"] = fpan;
item["M_Name"] = mn;
item["M_PAN"] = mpan;
jsonObj.push(item);
customerString = JSON.stringify(jsonObj);
}
function accountDetails() {
jsonObj = [];
accountNum = $('textarea#fno').val();
item = {}
item["ACNum"] = accountNum;
jsonObj.push(item);
accString = JSON.stringify(jsonObj);
}
when user enter details onto html form than I used jQuery to get JSON String of customer details and account details .Now I want to store these JSON string into application or session variable where customer details will store into one session variable and account details will store into another session variable.
I am using but is not working
No, you can not do this because serverside code executes before the javascript. You can do this by using hiddenfield, set hiddenfield value from jquery and get that from your serverside.

Action Not Firing When Button Clicked

I have a Razor Index page with a button, that when clicked should run an action on the Home Controller, but when I debug the home controller, the action is not firing and the break point not being hit.
The Razor code is:
#{
ViewBag.Title = "csi media web test";
}
<div class="jumbotron">
<h1>csi media web test</h1>
<p class="lead">Liane Stevenson</p>
</div>
<div class="row">
<div class="col-md-12">
<div class="panel panel-info">
<div class="panel-heading"><i class="glyphicon glyphicon-arrow-right"></i> Enter Your Four Numbers</div>
<div class="panel-body">
<form class="form-inline">
<div class="col-md-9">
<div class="form-group">
<label class="sr-only" for="number1">1st Number</label>
<input type="number" class="form-control" id="number1" name="Number1" placeholder="#1">
</div>
<div class="form-group">
<label class="sr-only" for="number2">2nd Number</label>
<input type="number" class="form-control" id="number2" name="Number2" placeholder="#2">
</div>
<div class="form-group">
<label class="sr-only" for="number3">3rd Number</label>
<input type="number" class="form-control" id="number3" name="Number3" placeholder="#3">
</div>
<div class="form-group">
<label class="sr-only" for="number4">4th Number</label>
<input type="number" class="form-control" id="number4" name="Number4" placeholder="#4">
</div>
</div>
<div class="col-md-3 text-right">
<button class="btn btn-default" onclick="location.href='#Url.Action("SortDesc", "Home")'"><i class="glyphicon glyphicon-arrow-down"></i> Sort Desc</button>
<button class="btn btn-default" onclick="location.href='#Url.Action("SortAsc", "Home")'"><i class="glyphicon glyphicon-arrow-up"></i> Sort Asc</button>
</div>
</form>
<p>
#if (Model != null)
{
foreach (int number in Model.Numbers)
{
<span class="label label-info">#number</span>
}
}
</p>
</div>
</div>
</div>
</div>
And the Action is:
public ActionResult SortDesc (string number1, string number2, string number3, string number4)
{
NumberSetList list = new NumberSetList();
List<int> numbers = new List<int>();
numbers.Add(Convert.ToInt32(number1));
numbers.Add(Convert.ToInt32(number2));
numbers.Add(Convert.ToInt32(number3));
numbers.Add(Convert.ToInt32(number4));
numbers.OrderByDescending(i => i);
list.SortOrder = "Desc";
return View(list);
}
When it runs it does however change the URL of the page to:
http://localhost/Home/Index?number1=5&number2=4&number3=3&number4=9
So it's almost as if it knows the action is there and what it takes but it just doesn't run it?
What you need is a anchor tag and not a button. Having a link on a tag will actually change the browser URL to the value given in its href. Where as a button will do nothing. To change the URL you will have to add additional Javascript to handle it.
So change this
<button class="btn btn-default" onclick="location.href='#Url.Action("SortDesc", "Home")'">
<i class="glyphicon glyphicon-arrow-down"></i> Sort Desc
</button>
to
<a class="btn btn-default" href="#Url.Action("SortDesc", "Home")">
<i class="glyphicon glyphicon-arrow-down"></i> Sort Desc
</a>
Do the same changes to your other button syntax too.
This code is pseudo code and is untested but this should give you an idea
put this in your models folder
public class myViewModel
{
public int Number1 {get; set;}
public int Number2 {get; set;}
public int Number3 {get; set;}
public int Number4 {get; set;}
}
change your controller to something like this
[HttpPost]
public ActionResult SortDesc (myViewModel model)
{
if(!ModelState.IsValid)
{
return View(list)
}
else
{
NumberSetList list = new NumberSetList();
List<int> numbers = new List<int>();
numbers.Add(model.Number1);
numbers.Add(model.Number2));
numbers.Add(model.Number3));
numbers.Add(model.Number4));
numbers.OrderByDescending(i => i);
list.SortOrder = "Desc";
return View(list);
}
}
this will tell you if your model is valid or not, but I suspect your data is being passed and read as an integer rather than a string, so you could try changing the object type first and then try model binding
but on a review of my code just then, you might be missing the [HttpPost] attribute at the start of the code block which would mean this is always a HttpGet

The id is missed when form is posted to controller

I am developing a mvc website.I have a table called member .this table has a controller and the controller has an edit method as you can see :
public ActionResult Edit()
{
int userId = _memberRepository.ReturnMemberIdByMobile(User.Identity.Name);
ViewBag.Edit = _memberRepository.FindById(userId).First();
return View();
}
[HttpPost]
public ActionResult Edit(Member value)
{
try
{
if (_memberRepository.Edit(value))
{
value.RegisteredDate = DateTime.Now;
_memberRepository.Save();
TempData["Success"] = "با موفقیت ویرایش شد ...";
string strLocation = HttpContext.Server.MapPath("~/Image/users");
if (value.ImgByte != null)
{
value.ImgByte.SaveAs(strLocation + #"\" + value.Id + ".jpg");
}
}
}
catch (Exception)
{
TempData["Error"] = "ویرایش نشد، لطفاً مجدداً تلاش نمایید";
}
return RedirectToAction("Edit");
}
The edit view is correctly work.the problem is when i post my view to edit controller .the id of member is changed to 0 it means it is missed.why ?and the value can't be edited.
#using DCL
#{
ViewBag.Title = "Edit";
Layout = "~/Areas/user/Views/Shared/_shared.cshtml";
Member membervalue = new Member();
membervalue = ViewBag.Edit;
}
#using (#Html.BeginForm("Edit", "User", FormMethod.Post,
new {id = "form", enctype = "multipart/form-data"}))
{
if (TempData["Error"] != null)
{
<div class="pad margin no-print">
<div class="callout callout-info" style="margin-bottom: 0 !important; background-color: #ea0000 !important; border-color: #d20000">
#TempData["Error"]
</div>
</div>
}
if (TempData["Information"] != null)
{
<div class="pad margin no-print">
<div class="callout callout-info" style="margin-bottom: 0 !important; background-color: orangered !important; border-color: red">
#TempData["Information"]
</div>
</div>
}
if (TempData["Success"] != null)
{
<div class="pad margin no-print">
<div class="callout callout-info" style="margin-bottom: 0 !important; background-color: #00A65A !important; border-color: #00925A">
#TempData["Success"]
</div>
</div>
}
<div class="row">
<!-- general form elements -->
<div class="col-xs-12">
<div class="box">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">حساب کاربری</h3>
</div>
<!-- /.box-header -->
<!-- form start -->
<div class="box-body">
<div class="col-lg-7">
<div class="input-group">
<label for="Name">نام</label>
<input class="form-control" id="Name" name="Name" type="text" value="#membervalue.Name">
</div>
<div class="input-group">
<label for="family">نام خانوادگی</label>
<input class="form-control" id="family" name="family" type="text" value="#membervalue.Family">
</div>
<div class="input-group">
<label for="mobile">موبایل</label>
<input class="form-control" id="mobile" name="mobile" type="text" value="#membervalue.Mobile">
</div>
<div class="input-group">
<label for="password">رمز عبور</label>
<input class="form-control" id="password" name="password" type="password" value="#membervalue.Password">
</div>
<div class="input-group">
<label for="Email">ایمیل</label>
<input class="form-control" id="Email" name="Email" type="text" value="#membervalue.Email">
</div>
<div class="form-group">
<label for="ImgByte">عکس </label>
<input id="ImgByte" name="ImgByte" type="file">
</div>
<input type="hidden" id="Id" name="id" value="#membervalue.Id">
</div>
</div>
<!-- /.box-body -->
</div>
</div>
</div>
<!-- /.box -->
</div>
<div class="row" style="margin: 0; margin-bottom: 20px">
<div class="box-footer" style="direction: ltr">
<button type="submit" class="btn btn-info">ویرایش</button>
<a class="btn btn-gray" href="#Url.Action("Index", "Home", null)">انصراف</a>
</div>
</div>
}
Instead of using the viewbag for your model you should pass in the model as a strongly typed object. You can do this with the following change in the Action. Then in your view define the model at the top and you can use it throughout the code.
You will also need a #Html.HiddenFor tag for your id. Now it is no longer possible (without a compile time exception that is) to create a type-o. On your previous code maybe you cased Id incorrectly which would cause it not to be populated OR maybe the form field name was not cased correctly. This takes all those manual errors out of the equation.
public ActionResult Edit()
{
int userId = _memberRepository.ReturnMemberIdByMobile(User.Identity.Name);
var model = _memberRepository.FindById(userId).First();
return View(model); // pass this in as the model, do not use viewbag
}
View
#model = Member #* namespace qualified type *#
#*... editor code *#
#Html.HiddenFor(x => x.Id)
#Html.TextboxFor(x => x.Name) #* do this instead of manual input *#
I ran your code, and there is no mistake in it. Id is passed correctly to Edit (post) action. The only reason it can be empty in the code that you show is that FindById returned entity without Id property set.

Categories

Resources