I've read 100 articles and tried everything, but I cannot seem to get my form data (on an aspx page) to post to my Web API controller.
Here is my ridiculously simple HTML:
<form id="form1" method="post" action="/api/WebApi/TestPost">
<input type="text" id="someinput" name="someinput" />
<input type="submit" value="Submit Me" id="mysubmit" />
</form>
Here is my ridiculously simple controller code:
public class WebApiController : ApiController
{
[System.Web.Mvc.HttpPost]
public string SomeOtherPost()
{
//This one ALWAYS gets hit
return "1";
}
[System.Web.Mvc.HttpPost]
public string TestPost(string someinput)
{
//This one NEVER gets hit
return "2";
}
}
The action with no parameters always gets hit, the action with the string parameter never gets hit.
This seems like it should be super easy. What on earth am I missing?
Related
I basically have a contact form, which I need to POST to my Umbraco backend. The frontend looks similar to this:
using (Html.BeginUmbracoForm("HandleFormSubmit", "ContactForm", FormMethod.Post)) {
<form>
<input name="Name" type="text" />
<button type="submit">Send</button>
</form>
}
I then have a surface controller in /Controllers/ContactFormController.cs that looks like:
public class ContactFormController : SurfaceController {
// GET: ContactForm
public ActionResult Index() {
return PartialView("ContactForm", new ContactForm());
}
[HttpPost]
public ActionResult HandleFormSubmit(ContactForm model) {
return RedirectToCurrentUmbracoPage();
}
}
I am trying to hit the HandleFormSubmit POST method. The GET method works (breakpoint proves that). No matter what I do, I cannot get it to hit this method. I've looked at tons of guides and all of them seem to be the exact same as this.
The POST data is as follows:
url: /contact-us/
data: name="Test"
Content-Type: multipart/form-data
What am I doing wrong here? Using Umbraco 7.6.6
Your problem is that you are rendering form inside the form.
Your view should look like this:
using (Html.BeginUmbracoForm("HandleFormSubmit", "ContactForm", FormMethod.Post)) {
<input name="Name" type="text" />
<button type="submit">Send</button>
}
And it should work.
I am new to ASP.NET MVC. I was used to program using just ASP.NET. I want to do something when the user clicks a button. I am not understanding what do I do at Controller.
I have this View:
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#Html.Action("RegisterHour", "Register")
and the Controller:
public ActionResult RegisterHour()
{
//TODO: do anything
return View("Index");
}
When I click at the button, I would like to stay in the same page (it can reload). I simply want to do something like go to the database and create a new entity, and then show a messagebox.
This code causes an stackoverflow. What am I missing? What do I have to change at Controller?
Thanks.
The line
#Html.Action("RegisterHour", "Register")
actually makes a request to the server in order to render the result of the "RegisterHour" action. So in order to render the result of the action the first time, you need to make a request to the same action. This causes an endless loop, hence the stack overflow.
You are thinking in events, rather than thinking about HTTP and the web.
ASP.NET MVC embraces the HTTP protocol and you have to know what happens when a request is made and how HTML is rendered.
If you want to implement the scenario you are describing, you have to put a form on the page. The button can submit that form by making a POST request to some other action, and then the action can render a view showing the result. But for simply showing a message box, I don't think it is a good idea.
This is how desktop apps work, not web apps. You are trying to fit a square peg through a round hole.
there are many ways to get back to the controller. without post back look into ajax calls. the simplest way is the post back. put your view in a form tag either html or html.beginform
#using (Html.BeginForm()){
<input type="submit" value="submit"/>
}
as #Chuck mentioned on your controller then have a post method with the same name as the get you show
[HttpPost]
public ActionResult RegisterHour()
{
//TODO: do anything
return View(model);
}
the #Html.Action that you have will return a url so that is put inside another element. something like
<a src="#Html.Action("Action", "Controller")">Click Here</a>
if you want to stay in the same page instead of
return View("index");
use
return View();
Edit:
If you want a complete code of a do something stuff here you are:
Model
public ActionResult MyModel()
{
[Required]
public int propriety1 { get; set; }
}
Controller
public ActionResult DoSomething()
{
var model = new MyModel();
return View(model);
}
[HttpPost]
public ActionResult DoSomething(MyModel model)
{
if(ModelState.isValid){
//DO something
}else{
return View(model);
}
}
View
#model Models.MyModel
#using (Html.BeginForm())
{
#Html.LaberlFor(m=>m.propriety1) #Html.TextBoxFor(m=>m.propriety1)
<input type="submit" value="Click me" />
}
Create an endpoint and have the form submit to it.
UI Code
<form action="/Registration/RegisterHour" >
<p>
<label>Username</label>
<input type="text" name="username" />
</p>
<p>
<label>First Name</label>
<input type="text" name="firstname" />
</p>
<p>
<label>Last Name</label>
<input type="text" name="lastname" />
</p>
<p>
<label>Password</label>
<input type="text" name="password" />
</p>
<p>
<label>Confirm</label>
<input type="text" name="confirm" />
</p>
<input type="submit" value="Save" />
</form>
Model
public class Registration
{
public string Username {get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
public string Password {get; set;}
public string Confirm {get; set;}
}
Typically you'll have two of the same endpoints, one is for the get, the other is for the post.
public class RegistrationController : Controller
{
//Get
[HttpGet]
public ActionResult RegisterHour()
{
//TODO: do anything
return View("Index");
}
//Post
[HttpPost]
public ActionResult RegisterHour(Registration newUser)
{
if(Model.IsValid)
{
//Save user to the database
userRepository.AddUser(newUser);
//load success screen.
return RedirectAction("SuccessfulRegistration");
}
//If Model is invalid handle error on the client.
return View("Index");
}
}
I am learning MVC, following THIS tutorial. (link will take you directly to where i'm stuck). so far I have learnt, there's a controller for every view. Now i have to take input from user through web entry form as mentioned in tutorial. In my project, i have a controller named Default1 and i can run it as localhost:xyz/Default1/Index. it runs perfect.
Then i created a new Controller, named Default2 and bound it to some view to display some data, and it worked perfect as localhost:xyz/Default2/Displaycustomer. the customer information was static (hard coded). and controller is as:
public ViewResult DisplayCustomers()
{
Customer cobj = new Customer();
cobj.Code = "12";
cobj.Name = "Zeeshan";
cobj.Amount = 7000;
return View("DisplayCustomers",cobj);
}
Now i have to take input from User, regarding cutomer iformation, using html page as mentioned in tutorial. so i tried adding a new webform under view folder, and and modified my controller as:
[HttpPost]
public ViewResult DisplayCustomers()
{
Customer cobj = new Customer();
cobj.Code = Request.Form["Id"].ToString();
cobj.Name = Request.Form["Name"].ToString();
cobj.Amount = Convert.ToDouble(Request.Form["Amount"].ToString());
return View("DisplayCustomers",cobj);
}
My Question is: How can i make my project stared, so that it takes input first, and then displays it, using above controller? Did i add the webform at right location? What would be the link to run it? i tried localhost:xyz/Default2/entryform etc. but failed.
(in my entryform.aspx, i have mentioned form action="DisplayCustomer" )
It sounds like what you're missing is an action to just display the form. In otherwords, you just need an action to display a form. That form's POST action should reference your controller's DisplayCustomers action.
So in your controller code:
public class CustomerController : Controller
{
[HttpGet]
public ViewResult New()
{
return View("NewCustomer"); //Our view that contains the new customer form.
}
// Add your code for displaying customers below
}
And in your view, you have code like this
#using(Html.BeginForm("DisplayCustomers", "Customer")) {
<!-- Add your form controls here -->
}
Notice that I'm using the version of the BeginForm helper that specifies the action method and controller to call. This will write the form tag to post back to your DisplayCustomers action. Here is the equivalent HTML:
<form method="POST" action="/Customer/DisplayCustomers">
You would then access your form using the URL http://test.server/Customer/New.
This may not be the best example in the world...but this will at least get you rolling..
url would be:localhost:1234/Home/Customer
the controller
public ActionResult Customer()
{
return View();
}
[HttpPost]
public ActionResult Customer(FormCollection frm)
{
var name = frm["name"].ToString();
var address = frm["address"].ToString();
ViewBag.Name = name;
ViewBag.Address = address;
return View();
}
The view
<div>
#using (Html.BeginForm())
{
<input type="text" name="name" id="name" />
<input type="text" name="address" id="address"/>
<input type="submit" name="submit" value="submit" />
<input type="text" name="namedisplay" value='#ViewBag.Name'/>
<input type="text" name="addressdisplay" value='#ViewBag.Address'/>
}
</div>
I'm requesting ASP.NET MVC the controller using the URL like this:
http://mysite.com/controller/myaction/Invalid%23name%25x
where Invalid%23name%25x is a parameter to
public ActionResult MyAction(string id) {
return View();
}
The GET request works fine.
MyAction view looks like this:
#using (Html.BeginForm()) {
...
<input name="Save" type="submit" value="Save" />
}
The generated HTML is:
<form action="/Controller/MyAction/Invalid#name%x" method="post">
...
<input name="Save" type="submit" value="Save" />
</form>
When I click on "Save", the form gets posted and the POST request goes to
http://mysite.com/controller/myaction/Invalid#name%x
i.e. the initial URL is decoded. This means the the POST action receives only the first part of the parameter - "Invalid"
[HttpPost]
public ActionResult MyAction(string id, ...) {
return View();
}
How can I prevent Html.BeginForm from decoding the initial URLs in order to preserve the initial state?
Pass ActionName and Controller in your form
#using (Html.BeginForm("ActionName", "Controller")) {
I would personally recommend you not to use id as string because as you have seen string can have many words in it.. let it mean what usually it does(numeric value).
use something like http://mysite.com/controller/myaction?Name=Invalid%23name%25x
public ActionResult MyAction(string Name) {
return View();
}
I suppose this would work for you..
In my Controller in a Asp.net MVC 1 app I want to use UpdateModel to populate a variable with POST data in my controller. I've looked at dozens of examples but even the most basic ones seem to fail silently for me.
Here's a very basic example that's just not working.
What am I doing wrong?
public class TestInfo
{
public string username;
public string email;
}
public class AdminController : Controller
{
public ActionResult TestSubmit()
{
var test = new TestInfo();
UpdateModel(test);//all the properties are still null after this executes
//TryUpdateModel(test); //this returns true but fields / properties all null
return Json(test);
}
}
//Form Code that generates the POST data
<form action="/Admin/TestSubmit" method="post">
<div>
<fieldset>
<legend>Account Information</legend>
<p>
<label for="username">Username:</label>
<input id="username" name="username" type="text" value="" />
</p>
<p>
<label for="email">Email:</label>
<input id="email" name="email" type="text" value="" />
</p>
<p>
<input type="submit" value="Login" />
</p>
</fieldset>
</div>
</form>
It looks like you're trying to get the controller to update the model based on the form elements. Try this instead:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult TestSubmit(TestInfo test)
{
UpdateModel(test);
return Json(test);
}
In your code, you're creating a new TestModel instead of letting the MVC runtime serialize it from the HttpPost. I've let myself get wrapped around the axel on this also, you're not the only one!
make properties of your public field:
public class TestInfo
{
public string username {get;set;}
public string email{get;set;}
}
I'm not too familiar with ASP.NET MVC, but shouldn't your TestSubmit method look more like this:
public ActionResult TestSubmit(TestInfo test)
{
UpdateModel(test);
return Json(test);
}
In the controller you should have two methods, one to respond to the GET, the other, if required is for responding to the POST.
So, firstly have a GET method:
public ActionResult Test ()
{
return View (/* add a TestInfo instance here if you're getting it from somewhere - db etc */);
}
Secondly, you'll need a POST method:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Test (TestInfo test)
{
return Json (test);
}
Notice that there's no UpdateMethod there, the ModelBinder would have done that for you.