FormCollection not populating - c#

I'm working on an MVC project which I want to pass a FormCollection, populated with form data, and post it to my action method in my controller. Here's an example of the view:
<asp:TextBox ID="txtClientLastName" name="txtClientLastName" runat="server" class="focus"/>
(Yes, I know! ASP controls in an MVC view isn't good but that's what I have. There's back end code in the view between tags as well which is why I haven't replaced them)
I've used a helper to link to my action:
<%=Html.ActionLink("Save","ClientInformationEdit",new {id=Model.PersonId})%
which calls my action:
public ActionResult ClientInformationEdit(int id, FormCollection form)
{
//rptLOA_GridCommands(form, id);
CIHelper ch = new CIHelper();
ch.person.LastName = form["txtClientLastName"];
db.SaveChanges();
return View(ch);
}
My ìdpasses the correct value but FormCollection form is null so form["txtClientLastName"] is null and I dont know why.

Add post attribute like below:
[HttpPost]
public ActionResult ClientInformationEdit(int id, FormCollection form)
{
//rptLOA_GridCommands(form, id);
CIHelper ch = new CIHelper();
ch.person.LastName = form["txtClientLastName"];
db.SaveChanges();
return View(ch);
}
If you want to post form on click of hyperlink then add following code:
<%=Html.ActionLink("Save","ClientInformationEdit",new {id=Model.PersonId,onclick="document.getElementById('form-id').submit();"})%>

try this:
#using (Html.BeginForm("Save", "ClientInformationEdit", FormMethod.Post))
{
<input type="hidden" value="#Model.PersonId"/>
<asp:TextBox ID="txtClientLastName" name="txtClientLastName" runat="server" class="focus"/>
<input type ="submit"/>
}
in your view

Related

How to retrieve input's value from a textbox

I'm learning to develop a webapp using .net and I'm having a problem in retrieving the value from an <input>
Size:
#using (Html.BeginForm("GetList", "User", FormMethod.Post))
{
#Html.TextBoxFor(Model => Model.PageSize)
<input type="submit" value="Invia" />
}
I want to retrieve the value posted and then use it as a parameter in the url but all I try isn't working and all this is frustrating me a lot, thanks for the help.
In your Post method in the Controller, define an input variable with the same datatype of the model that you are using in the view. Then you will be able to get the values that you have on the screen.
What happens is that when the submit button is pressed, all the input values will be submitted to Controller's post method.
Supposing that your model's datatype is "User", the Controller's Post method should look like the below:
[HttpPost]
public ActionResult GetList(User model)
{
int pageSize = model.PageSize;
...
return View();
}

Send Selected DropDownList value to HomeController ActionResult

Hi I have a drop down list that is filled in from comma delimited values in the config. This works fine.
What I am trying to do is to send the selected value on button click to a ActionResult in the HomeController.
I created a Model, which is taking a string. When I hit the button I get error:
The view 'TestAction' or its master was not found or no view engine supports the searched locations.
This is what my Controller looks like:
[HttpPost]
[ActionName("TestAction")]
public ActionResult TestAction(SQL_Blocks_App.Models.DropdownList SelectedValue)
{
//System.Diagnostics.Debug.WriteLine(SelectedValue);
return View();
}
This is what my model looks like:
public class DropdownList
{
//
// GET: /DropdownList/
[Display(Name = "Servers")]
public string SelectedValue{ get; set; }
}
and this is what my Index View looks like:
<form id="SelectedValue" action="/Home/TestAction" method="post" style="margin: 0">
<div class="col-lg-5">
#{
ViewBag.Title = "Index";
}
#Html.DropDownList("YourElementName", (IEnumerable<SelectListItem>)ViewBag.DropdownVals, "--Choose Your Value--", new
{
//size = "5",
style = "width: 600px"
})
</div>
<div class="col-lg-5">
<input type="submit" value="Run Query" />
<input id="Button2" type="button" value="Clear" onclick="window.location.reload()" />
</div>
</form>
I want to clarify. My end goal is to use the selected value in a SQL query in the ActionResult and return the results back to the index so I can fill them in a table. ( You don't have to show me how to do the SQL part for now I just would like to see the selected value at least printed in the output.)
Redirect to index action, and pass the parameters along
[HttpPost]
[ActionName("TestAction")]
public ActionResult TestAction(SQL_Blocks_App.Models.DropdownList _selectedValue)
{
//System.Diagnostics.Debug.WriteLine(SelectedValue);
return RedirectToAction("Index", "[Controller]", new {#_selectedValue = _selectedValue });
}
and then your Index method should accept the parameter.
[HttpGet]
public ActionResult Index(SQL_Blocks_App.Models.DropdownList _selectedValue)
{
//use _selectedValue
}
I would recommend using another method other than your index, or make Dropdownlist nullable/set a default for it.
The default framework behavior of return View() is to return a view with the same name as the currently-executing action. Which is TestAction. The error is telling you that no such view was found.
You have a couple of options. You can either create the view, or you can return something else. For example, if you want to redirect back to the Index then you can return a redirect result:
return RedirectToAction("Index");
You could also specify the Index view in the response:
return View("Index");
However, keep in mind that the URL will still be for TestAction and not for Index, which could result in unexpected changes to behavior if you're not aware of this.
Edit: Based on comments on this answer, it sounds like what you actually want is to build a pair of actions which generally operate on the same view. This isn't particularly common for an index view, but is very common for edit views. The only difference is semantics, structurally the concept works anywhere.
Consider two actions:
public ActionResult Index()
{
// just show the page
return View();
}
[HttpPost]
public ActionResult Index(SQL_Blocks_App.Models.DropdownList SelectedValue)
{
// receive data from the page
// perform some operation
// and show the page again
return View();
}
Requests between these two actions would differ only by the HTTP verb (GET or POST), not by the action name on the URL. That name would always be "Index". But when the form on the index view is submitted via POST and has a "SelectedValue", the second action is invoked instead of the first.
In that second action you would perform your database interaction, gather whatever data you needed, and if necessary include a model or some additional data in the response.
You TestAction method is returning to a View. Make sure View TestAction.cshtml exists and is in the Home folder.

html form posting to mvc controller

I am trying to set up a simple login html page, whose action is sent to mvc controller on another of my sites. I have no problem setting up the page to do the post, and in the mvc controller I have my method that reads the form post. The problem is that I am not seeing my fields from the html form in the form collection.
Is there something special that I need to do to read a form post within a mvc controller method, if so what is that?
The is the form action markup from my page
<form action="http://reconciliation-local.sidw.com/login/launch" method="post">
User Name <input type="text" id="username"/><br/>
Password <input type="text" id="password"/>
<input type="submit" value="launch"/>
</form>
The controller method
[HttpPost]
public ActionResult launch(FormCollection fc)
{
foreach (string fd in fc)
{
ViewData[fd] = fc[fd];
}
return View();
}
When I step through the controller method code, I am not seeing anything in the formcollection parameter.
Post Html To MVC Controller
Create HTML page with form (don't forget to reference a Jquery.js)
<form id="myform" action="rec/recieveData" method="post">
User Name <input type="text" id="username" name="UserName" /><br />
Password <input type="text" id="password" name="Password"/>
<input type="submit" id="btn1" value="send" />
</form>
<script>
$(document).ready(function () {
//get button by ID
$('#btn1').submit(function () {
//call a function with parameters
$.ajax({
url: 'rec/recieveData', //(rec)= Controller's-name
//(recieveData) = Action's method name
type: 'POST',
timeout: '12000', (optional 12 seconds)
datatype: 'text',
data: {
//Get the input from Document Object Model
//by their ID
username: myform.username.value,
password: myform.password.value,
}
});
});
});
</script>
Then in The MVC Controller
controller/action
| |
1. Create Controller named rec (rec/recieveData)
Create View named rec.cshtml
Here is the controller:
public class recController : Controller
{
// GET: rec
string firstname = "";
string lastname = "";
List<string> myList = new List<string>();
public ActionResult recieveData(FormCollection fc)
{
//Recieve a posted form's values from parameter fc
firstname = fc[0].ToString(); //user
lastname = fc[1].ToString(); //pass
//optional: add these values to List
myList.Add(firstname);
myList.Add(lastname);
//Importan:
//These 2 values will be return with the below view
//using ViewData[""]object...
ViewData["Username"] = myList[0];
ViewData["Password"] = myList[1];
//let's Invoke view named rec.cshtml
// Optionaly we will pass myList to the view
// as object-model parameter, it will still work without it thought
return View("rec",myList);
}
}
Here is the View:
#{
ViewBag.Title = "rec";
}
<h2>Hello from server</h2>
<div>
#ViewData["Username"]<br /> <!--will display a username-->
#ViewData["Password"] <!-- will display a password-->
</div>
If you posted some code it would be much easier to help you, so please edit your question...
Make sure that your form's action has the correct address, that your method is specifying POST (method="POST") and that the input fields under your form have name attributes specified.
On the server side, try making your only parameter a FormCollection and test that the fields in your form posted through the debugger. Perhaps your model binding isn't correct and the FormCollection will at least show you what got posted, if anything.
These are just common issues I've seen. Your problem could be different, but we need to see what you're working with to be able to tell.
Try something like this:
cQuery _aRec = new cQuery();
_aRec.Sqlstring = "SELECT * FROM Admins";
DataSet aDS = _aRec.SelectStatement();
DataTable aDT = aDS.Tables[0];
foreach (DataRow aDR in aDT.Rows){
if (txtAdminUsername.Text == aDR[0].ToString()){
if (txtAdminPassword.Text == aDR[1].ToString()){
Session["adminId"] = aDR[0];
Response.Redirect("Admin.aspx");
return;
}
}
}
Make sure that your FormCollection object properties for username and password are defined properly.
I had to use the name attribute on the text tag, and that solved my problem, is now working like a charm.
You have to use Ajax to do that.. Whenever you want to "submit" from client side, you should use Ajax to update the server
Step 1 - you redirect your Ajax call to your action, but with your list of parameters in the query-string appended
$.ajax(url: url + "?" + your_query_string_parameter_list_you_want_to_pass)
Step 2 - add optional parameters to your Controller-action with the same names and types you expect to get returned by the client
public ActionResult MyControllerAjaxResponseMethod(type1 para1 = null,
type2 para2 = null,
type3 para3 = null, ..)
Know that the optional parameters have to be initialized, otherwise the Action itself will always ask for those
Here's where the "magic" happens though --> MVC will automatically convert the query-string parameters into your optional controller-parameters if they match by name
I was also looking for a good answer for this, --> i.e. - one that doesn't use q-s for that usage, but couldn't find one..
Kinda makes sense you can't do it in any other way except by the url though..

Load View again by passing updated parameter to the same Controller MVC 3

I want to load the same view again by passing updated parameter from text input on the link click. I tried to use something like <a href="#Url.Action("Index", "Home", new {id = "txtCount".value }). Not sure if there is even a way to do this. I know I could use partial but I want to reload the whole page with updated parameter. Thanks in advance for any help.
Controller
[HttpGet]
public ActionResult Index(int id)
{
return View(id);
}
View
#model int
#using (#Html.BeginForm())
{
<input id="txtCount" value="1" />
Update
for (int i = 0; i < Model; i++)
{
<div>#i </div>
}
}
Maybe something like this
Go!
and binding with jquery
$("#mylink").click(function(){
document.location.href = '#Url.Content("~/Controller/Action")' + $("#mytxt").val();
return false;
});
Obviously with the proper validations if the textbox is empty and all that stuff.
You cannot add the id value to the #Url.Action because it is processed before on the server side, before the page is rendered

Multiple actions on the same controller and view in asp.net MVC

How do I use multiple actions on the same controller?
I'm using the default project that comes up when opening a new project in asp.net mvc.
I added one more Index action on the homecontroller to accept a value from a textbox...like this
string strTest;
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(FormCollection frm)
{
strTest = frm["testbox"];
return RedirectToAction("Index");
}
Now,I need to display the entered value back to the user. How do I do this?
I tried this..
public ActionResult Index()
{
this.ViewData.Add("ReturnMessage", strValue);
return View();
}
Here's what I've put on my view..
<% using (Html.BeginForm())
{ %>
<p>
<%=Html.TextBox("testbox")%>
</p>
<p>
<input type="submit" value="Index" /></p>
<p>
<%= Html.ViewData["ReturnMessage"] %>
</p>
<% } %>
the compiler typically doesn't let me add another index with same constructor to display the entered message back to the user which is obvious in c# I know. But,then how do I get the message back out to the user.
Thanks
Well, a controller matches one route, based on the parameters sent. You can layer your routes from most specific to least specific, it checks in order. First one that hits wins.
The other answer is to either strongly type your model sent to your view, or store it in the ViewData:
ViewData["Message"] = "Welcome to ASP.NET MVC!";
Then access it in your View:
<%= Html.Encode(ViewData["Message"]) %>
Simple method
In your view
<% using (Html.BeginForm()) {%>
<%= Html.TextBox("myInput") %>
<%= ViewData["response"] %>
<%}%>
In your controller;
public ActionResult Index()
{
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(FormCollection collection)
{
ViewDate.Add("response", collection["myInput"]);
return View();
}
Josh, see the previous question you asked.
In there I had <%= Html.textbox("myInput", Model.myInput....
it's the Model.myInput that will put the value from your model into the text of yoru text box.
EDIT
Or if you don't want it in a text box then simply do;
EDIT 2
You can add as many items into your new form view model and it has, in this case, nothing to do with a database. see your previous question on where i declared the class.
the class can have as many properties as you like. So you can add a string myResponse {get;set;} to return a response back to your view so then you can use <%=Model.myResponse%>
Hope this helps.

Categories