I am working on a sample mvc project in which I am trying to post data to a controller. I have posted sample (see below), but if I add [HttpPost] to method I am getting '404' error.
View:
<% using (Html.BeginForm()) { %>
<%= Html.Telerik().NumericTextBox()
.Name("NumericTextBox")
.Spinners(false)
.EmptyMessage("ID")
%>
<input type="submit" value="Submit" />
<% } %>
Controller:
[HttpPost]
public ActionResult GetDetails(int id)
{
return View();
}
**I also tried,**
[HttpPost]
public ActionResult GetDetails(FormCollection collection)
{
return View();
}
Route:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Customer", action = "GetDetails", id = UrlParameter.Optional } // Parameter defaults
);
You'll want the Name to match the parameter on the controller, so I believe it should be like this:
Html.Telerik().NumericTextBox()
.Name("id")
Notes:
Although you specified UrlParameter.Optional on the id route parameter, it's not truly optional unless you make it nullable (ie, int? id) in the controller action.
Normally you should use GET and not POST for HTTP requests that don't change anything on the server, which seems to be the case here.
You should use the second method, but instead of FormsCollection, use:
GetDetails(int NumericTextBox)
The parameter must be the same name as the input box.
Related
so I recently started project in .net MVC and have been having issues preserving data. I read somewhere that in order to do so, you have to pass the model back and forth. I tried doing this, but it still runs into issues. In my project, I have two buttons right now, getData and getData2. My view prints their true/false values. When I press one, it turns true, but if I press the other, it turns true but the other one goes to false. I want them both to stay true if I press them both.
Controller:
[HttpPost]
public ActionResult GetData(TestSite.Models.FarModels theFars)
{
theFars.HasData = true;
return RedirectToAction("FarCalc",theFars);
}
[HttpPost]
public ActionResult GetData2(TestSite.Models.FarModels theFars)
{
theFars.HasData2 = true;
return RedirectToAction("FarCalc", theFars);
}
[HttpGet]
public ActionResult FarCalc(TestSite.Models.FarModels theFars)
{
return View(theFars);
}
View:
#using (Html.BeginForm("GetData", "Home", FormMethod.Post))
{
//#Html.TextBoxFor(model => model.FarValue)
<input type="submit" value="GetData" />
}
#using (Html.BeginForm("GetData2", "Home", FormMethod.Post))
{
//#Html.TextBoxFor(model => model.FarValue)
<input type="submit" value="GetData2" />
}
#Model.HasData
#Model.HasData2
Thanks
You would need to make use of TempData object because the use of RedirectToAction returns a status code of 302, and the model binding does not exist. A good example is below.
https://www.codeproject.com/Tips/842080/How-to-Persist-Data-with-TempData-in-MVC
I'm using the Ajax.BeginForm helper in ASP.NET MVC3 to submit a form that replaces itself with new values in the form set on the server. However when I use helpers like Html.TextBoxFor I get the values that was submitted, not the values I inserted into the model on the server.
For example; I set SomeValue to 4 in my action and show it in a textbox. I change the value to 8, hit submit and would expect the value to be changed back to 4 in the textbox, but for some reason it stays 8. But if I output SomeValue without using Html helpers it says 4. Anybody have some clue about what is going on?
My controller:
public ActionResult Index(HomeModel model)
{
model.SomeValue = 4;
if (Request.IsAjaxRequest())
return PartialView(model);
return View(model);
}
public class HomeModel
{
public int? SomeValue { get; set; }
}
My View (please not that I have all the needed javascript in my layout page):
<div id="ajaxtest">
#using(Ajax.BeginForm(new AjaxOptions{ InsertionMode = InsertionMode.Replace,
UpdateTargetId = "ajaxtest", HttpMethod = "Post" })) {
#Html.TextBoxFor(model => model.SomeValue)
<input type="submit" value="Update" />
}
</div>
you can use
ModelState.Clear()
in your controller method to make the html helpers use your changed model. Otherwise they use the values from the form submit
Have a look at: Asp.net MVC ModelState.Clear
in your POST method you need to do
ModelState.Clear();
to reflect the changes made after the post
i have designed a view in asp .net mvc3 off course registration form. This is very simple form having name ,father name , qualification and a submit button , after pressing submit button i want to display information by using another view. please suggest me how can i send information from one view to another view.
my controller class is :
namespace RegistrationForm.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
// ViewBag.Message = "Welcome to ASP.NET MVC!";
//return View();
return RedirectToAction("registrationView");
}
public ActionResult About()
{
return View();
}
public ActionResult registrationView()
{
return View();
}
}
}
my view is :
#{
Layout = null;
}
registrationView
Enter Name
</td>
<tr>
<td>
Enter Father Name
</td>
<td>
<input type="text" name="fname" id="fname" />
</td>
<tr>
<td>
Enter Qualification
</td>
<td>
<input type="text" name="qly" id="qly" />
</td>
</tr>
</table>
<input type="submit" value="submit" />
</div>
well, we faced this problem before, and the best way to get this to work was to define a model that this page will work with, then use this model object when posting back, or redirecting to another view.
for your case, you can simply define this model in your Models folder
ex: RegistrationModel.cs file, and define your required properties inside.
after doing so, you will need to do 2 more steps:
1- in your GET action method, create a new RegistrationModel object, and provide it to your view, so instead of:
return View();
you will need something like:
var registrationModel = new registrationModel();
return View(registrationModel);
2- Use this model as a parameter in your POST Action method, something like
[HttpPost]
public ActionResult registrationView(RegistrationModel model)
{
// your code goes here
}
but don't forget to modify the current view to make use of the provided model. a time-saver way would be to create a new dummy View, and use the pre-defined template "Create" to generate your View, MVC will generate the properties with everything hooked up. then copy the generated code into your desired view, and omit any unneeded code.
this is a Pseudo reply. if you need more code, let me know
<% using Html.Form("<ActionName>") { %>
// utilize this HtmlHelper action to redirect this form to a different Action other than controller that called it.
<% } %>
use ViewData to store the value.
just remember that it will only last per one trip so if you try to call it again, the value would have been cleared.
namespace RegistrationForm.Controllers { public class HomeController : Controller { public ActionResult Index() { // ViewBag.Message = "Welcome to ASP.NET MVC!";
ViewData["myData"] = "hello world";
//return View();
return RedirectToAction("registrationView");
}
public ActionResult About()
{
return View();
}
public ActionResult registrationView()
{
// get back my data
string data = ViewData["myData"] != null ? ViewData["myData"].ToString() : "";
return View();
}
}
And you can actually usethe ViewData value on the html/aspx/ascx after redirect to the registrationView.
For example on the registrationView.aspx:
<div id="myDiv">
my data was: <%= ViewData["myData"] %>
</div>
You could simply in you method parameter list declare the parameters with the name of the controls. For example:
The control here has an id "qly"
<input type="text" name="qly" id="qly" />
Define your method parameter list as following:
public ActionResult YourMethod(string qly)
{
//simply pass your qly to another view using ViewData, TempData, or ViewBag, and use it in the desired view
}
You should use TempData which was made exactly for it, to persist values between actions.
This example is from MSDN (link above):
public ActionResult InsertCustomer(string firstName, string lastName)
{
// Check for input errors.
if (String.IsNullOrEmpty(firstName) ||
String.IsNullOrEmpty(lastName))
{
InsertError error = new InsertError();
error.ErrorMessage = "Both names are required.";
error.OriginalFirstName = firstName;
error.OriginalLastName = lastName;
TempData["error"] = error; // sending data to the other action
return RedirectToAction("NewCustomer");
}
// No errors
// ...
return View();
}
And to send data to the view you can use the model or the ViewBag.
I have a controller in an area called Admin
public class SiteVisitController : Controller
{
public ViewResult ReadyForCompletion() { ... }
public ViewResult CompleteAndExport() { ... }
}
and a view (ReadyForCompletion.cshtml) that has posts back to a different controller action on the same class
#using (Html.BeginForm( "CompleteAndExport", "SiteVisit" ))
{
<input type="submit" value="Complete & Export" />
}
The generated HTML for this form has a blank action:
<form action="" method="post"> <input type="submit" value="Complete & Export" />
</form>
I want to know why this has a blank action? For more info, I also added in a
#Url.RouteUrl(new { controller = "ReadyForCompletion", action = "SiteVisit", area = "Admin" })
which also printed out an empty string. Also, if I use an empty Html.BeginForm() it generates the correct action.
Registered routes are
context.MapRoute(
"Admin_manyParams",
"Admin/{controller}/{action}/{id}/{actionId}",
new { action = "Index", id = UrlParameter.Optional, actionId = UrlParameter.Optional }
);
I believe your problem is caused by having consecutive optional parameters. I was not able to replicate your problem until I changed the route to contain two optional parameters.
See: This article which explains the problem
For those of you encountering this issue using ASP.NET Core the root cause is the same, though the solution is slightly different. I first saw this in Core using multiple default values when calling .MapRoutes(). E.g.
routes.MapRoute(
name: "default",
template: "{controller}/{action}/{id?}",
defaults: new { controller = "Foo", action = "Bar" }
);
The workaround is to place the default values into the string template:
routes.MapRoute(
name: "default",
template: "{controller=Foo}/{action=Bar}/{id?}"
);
YMMV.
Any ideas why after adding Model Binding to the controller, the partial view no longer gets updated:
All I did was change the signature:
from:
public ActionResult About2()
to:
public ActionResult About2([Bind(Prefix = "SomePropertyToBind")] String modelString)
and here is the Ajax.BeginForm:
#using (Ajax.BeginForm("About2", "Home", new AjaxOptions { UpdateTargetId = "property22", InsertionMode = InsertionMode.Replace }))
{
#Html.DropDownListFor(m => m.ModelTest.SomePropertyToBind, new SelectList(Model.ModelTest.list, "property1", "property2"))
<button type="submit" id="test">Click me</button>
}
I've attached a sample: http://www.sendspace.com/file/7boodv
Thanks,
I downloaded your project and the problem is in the following code:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult About2([Bind(Prefix = "SomePropertyToBind")] String modelString)
{
using this attribute [AcceptVerbs(HttpVerbs.Post)] is the problem, you cannot open your desired page without having a GET action to serve your request.
of course removing this attribute worked perfectly, but if you need to reserve it, add another action with the same name to serve the GET request to your page like this:
public ActionResult About2()
{
// Initialization code for About2 page
}
That's it. feel free to ask if it's still not working, thanks.