MVC3 Wrong form submits - c#

From every page of a website I'm making, you're able to sign in. On pages with other forms, I get the following error after submitting: "Child actions are not allowed to perform redirect actions." All forms worked fine until I added the Sign In. In addition, the Sign In works correctly when you use it. The error only appears if I submit a different form. I've set a breakpoint and I've watched what happens when I hit the other submit. For some reason, the SignIn Post ActionResult is trying to run.
Any help would be appreciated.
Error:
Child actions are not allowed to perform redirect actions. Line 67: #{Html.RenderAction("SignIn", "Account");}
Sign In View
#using (Html.BeginForm("SignIn", "Account", FormMethod.Post))
{
<input class="signInSubmit" type="submit" name="submitButton" value="" />
}
Another Form in View
#using (Html.BeginForm("Confirm", "Cart", null, FormMethod.Post, new { #id = "productDetailsForm" }))
{
<input class="addToCart" type="submit" name="submit" value="" />
}
Sign In Controller
// GET: /Account/SignIn
public ActionResult SignIn()
{
return PartialView();
}
// POST: /Account/SignIn
[HttpPost]
public ActionResult SignIn(Customer customer)
{
try
{
//Stuff is here
return RedirectToAction("Index", "Home");
}
catch
{
return RedirectToAction("Registration");
}
}
Other form Controller
// GET: /Cart/
public ActionResult Index()
{
CartViewModel cart = getCart();
return View(cart);
}
//POST: Cart/Confirm
[HttpPost]
public ActionResult Confirm(int productID, bool certs, int quantity)
{
CartItemViewModel viewModel = new CartItemViewModel
{
Item = productRep.GetProductByID(productID),
Certs = certs,
Quantity = quantity
};
return View(viewModel);
}
HTML Source Code
<form action="/Account/SignIn" method="post">
<input class="signInSubmit" type="submit" value="" />
</form>
<form action="/Cart/Confirm" id="productDetailsForm" method="post">
<input class="addToCart" type="submit" value="" />
</form>

My solution
I renamed the POST ActionResult to anything other than SignIn. Does anyone understand why this works?
AccountController
// POST: /Account/Signed
[HttpPost]
public ActionResult Signed(Customer customer)
{
try
{
//Stuff is here
return RedirectToAction("Index", "Home");
}
catch
{
return RedirectToAction("Registration");
}
}

Related

Can't get values ​entered in ASP.NET MVC Form

First of all my codes:
ManageClass.cshtml:
#{
ViewData["Title"] = "Class' Management";
}
<br />
<h2>Add Class</h2>
<form method="post" asp-controller="AddClassDB" asp-action="">
<div class="container">
<div class="form-group">
</div> </div>
<label for="formGroupExampleInput2">Class Name</label>
<input type="text" class="form-control" id="classNameInput">
<br/>
<div class="float-right">
<button type="submit" class="btn btn-success">Add</button>
</div>
<br />
<h2>Manage Class</h2>
</form>
HomeController.cs:
using Microsoft.AspNetCore.Mvc;
using StudentWeb.Models;
using System.Diagnostics;
namespace StudentWeb.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
return View();
}
public ActionResult ManageClass()
{
return View();
}
public ActionResult AddClassDB(ClassTable _table)
{
Console.WriteLine(_table);
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
I will take the value of classNameInput in ManageClass.cshtml and save it to SQL. I will do the saving in the Controller, but I have not yet received the value entered by the user.
But after I enter the value in the input and press the submit button, I get the following result:
(page not found)
You are using the wrong value for asp-controller and asp-action for the form. Hence it generates the wrong action path for the form.
It should be:
<form method="post" asp-controller="Home" asp-action="AddClassDB">
...
</form>
By default, all the action methods in the controller are GET (method). You need to apply [HttpPost] attribute so that the AddClassDB is recognized as POST (method).
[HttpPost("AddClassDB")]
public ActionResult AddClassDB(ClassTable _table)
{
Console.WriteLine(_table);
// TO-DO Redirect to view that is existed
return View();
}

MVC Action not firing

Controller :
public ActionResult Insert()
{
return View();
}
public ActionResult Insert(Employee emp)
{
Employee emp1 = new Employee();
emp1.insert(emp);
return View();
}
cshtml
#using (Html.BeginForm("Employee", "Insert", FormMethod.Post))
{
#Html.TextBoxFor(model => model.name)
#Html.TextBoxFor(model => model.Email)
#Html.TextBoxFor(model => model.mob)
<input type="button" value="Register me" />
}
I have to save my model values on button click ('Register me'). Thanks in advance.
Try to set attributes in your controller:
[HttpGet] // here ([HttpGet] is default so here you can delete this attribute)
public ActionResult Insert()
{
return View();
}
[HttpPost] // here
public ActionResult Insert(Employee emp)
{
Employee emp1 = new Employee();
emp1.insert(emp);
return View();
}
To call some action you need to submit your form. Change your button to submit type:
<input type="submit" value="Register me" /> // type="button" -> type="submit"
Also, in BeginForm you should firstly specify action name and then controller name:
#using (Html.BeginForm("Insert", "Employee", FormMethod.Post))
Its Because you have not declared HTTP POST on INSERT action
[HttpPost]
public ActionResult Insert(Employee emp)
{
Employee emp1 = new Employee();
emp1.insert(emp);
return View();
}
When you are using Beginform and your FormMethod is Post the related Action needs to have same kind of HTTP, By the way it doesn't matter if you have [HttpGet] on first ActionResult Because in MVC, any ActionResult that haven't declared any type of HTTP request/respond are known as [HttpGet]
Also in your BeginForm():
#using (Html.BeginForm("ActionName(Insert)", "ControllerName", FormMethod.Post))
{
#Html.TextBoxFor(model => model.name)
#Html.TextBoxFor(model => model.Email)
#Html.TextBoxFor(model => model.mob)
<input type="submit" value="Register me" />
}

How do i pull user entered text data from a view for http POST?

I have written a basic GET method for my CheckoutController that returns the view, the view will have text boxes for my user to enter payment information and promo code. How do I access this data in the POST method?
// GET: Checkout
public ActionResult PaymentsAndPromotions()
{
return View();
}
[HttpPost]
public ActionResult PaymentsAndPromotions()
{
var order = new Order();
try
{
if (db.Promotions !== PromoCode)
{
return View(order);
}
else
{
//save the order
db.Orders.Add(order);
db.SaveChanges();
//process the order
var cart = ShoppingCart.GetCart(this.HttpContext);
cart.CreateOrder(order);
return RedirectToAction("Complete", new object{id = order.OrderID});
}
}
catch
{
//invalid - redisplay with error
return View(order);
}
}
View code:
<form>
Payment Method:<br /><br />
Credit Card #: <br />
<input type="text" name="CreditCardNum" /><br />
Credit Card Type: <br />
<input type="text" name="CreditCardType" /><br/>
Promo Code: <br />
<input type="text" name="PromoCode"/> <br />
I suggest you to create a model something like this:
public class Order
{
public string CreditCardNum { get;set; }
public string CreditCardType { get;set; }
public string PromoCode { get;set; }
}
And from your controller, do this:
public ActionResult PaymentsAndPromotions()
{
var order = new Order();
return View(order);
}
[HttpPost]
public ActionResult PaymentsAndPromotions(Order order)
{
//you can get all your order's property here.
//example:
if (order.CreditCardNum != "test123")
{
}
return View(order);
}
In your view, you can do something like this (assuming you are using razor syntax):
#model Models.Order
#using (Html.BeginForm())
{
#Html.TextBoxFor(m => m.CreditCardNum)
#Html.TextBoxFor(m => m.CreditCardType)
#Html.TextBoxFor(m => m.PromoCode)
<input type="submit" value="Submit"/>
}
adirks95, in controller you can fetch form data using such code: Request.Form["CreditCardNum"]. Please let me know if you still have any issues.

ViewBag for video upload?

I am working with sample from codeproject http://www.codeproject.com/Tips/1011040/Upload-and-Delete-Video-File-to-Microsoft-Azure-Bl
I have created an index.cshtml in the way of
that is
#model List<string>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#using (Html.BeginForm("Add", "Blob", FormMethod.Post, new
{enctype = "multipart/form-data" }))
{
<div>
<input type="file" name="pic" id="pic" />
<input type="submit" value="Upload Now" id="s1" />
</div>
}
<ul>
#foreach (var item in Model)
{
<li>
<input type="button" name="b1" id="b1"
value="Delete"
onclick="Remove('#item')" />
<video src="#item" height="200" width="200" controls />
</li>
}
</ul>
#section scripts{
<script>
function Remove(x) {
alert(x);
var uri = "/Blob/remove";
$.post(uri, { name: x }, function (y) {
window.location.href = "/blob/index";
alert(y);
});
}
</script>}
and my Controller class is :
public class BlobsController : Controller
{
//
// GET: /Blobs/
BlBlobs objbl = new BlBlobs();
public ActionResult Index()
{
//return View();
return View(objbl.GetBlobList());
}
[HttpPost]
public ActionResult Add(HttpPostedFileBase pic)
{
objbl.AddBlob(pic);
return RedirectToAction("Index");
}
[HttpPost]
public string Remove(string name)
{
objbl.DeleteBlob(name);
return "Blob Removed Successfully";
}
}
That give me pretty nice browse/upload form, but fails on upload click with 404 error. The question is - how to call the add method correctly in this index.cshtml file?
Your controller is called BlobsController so that would give you a route of /blobs/{action} with the default route, however in your view your actions are looking for a controller called blob. Either change the name of your controller
public class BlobController : Controller
{
//...
}
Or update your views to use the correct controller name.
Html.BeginForm("Add", "Blobs", FormMethod.Post, new
{enctype = "multipart/form-data" }))

ASP.NET MVC form input not working as expected

Trying to understand why my page doesn't work as expected. I was expecting the SignIn method on the controller to be called when clicking submit button, however, StartGame is still be called instead. The page originates through this URL: http://{domain}/Play/StartGame
Markup:
#{
ViewBag.Title = "Start Game";
}
<h2>StartGame</h2>
#using (Html.BeginForm())
{
#Html.TextBox("gamerId");
<input type="submit" value="SignIn" class="btn btn-default" />
}
Controller:
public class PlayController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult StartGame()
{
return View();
}
public ActionResult SignIn(string gamerId)
{
return View();
}
}
What am I missing here?
You need to specify the action in your BeginForm().
#using (Html.BeginForm("SignIn","Play"))
{
#Html.TextBox("gamerId");
<input type="submit" value="SignIn" class="btn btn-default" />
}
Or another option is to create an overload action and use an attribute:
[HttpPost]
public ActionResult StartGame(string gamerId)
{
return View();
}

Categories