parameters and action - c#

How can i pass to asp.net mvc action parameters like: line[first], line[second], line[third], people[john] etc?
For example we have html:
<form>
<input type="hidden" name="line[first]" value="hello" />`
<input type"submit" value="send" />
</form>
How we can take "line[first]" value when user clicks on send button?

[HttpPost, ValidateAntiForgeryToken]
public ActionResult ShowLogin(LoginModel model)
{
model.username;
model.password
}
instead of admin you can have
public ActionResult ShowLogin(FormCollection form)
{
var user = form["username"];
}

Related

.NET how to disable FluentValidation with formHelper on certain submit button

I'm using FluentValidation with FormHelper in order to validate my form using ajax.
My form has 2 submit buttons:
Default one that should run validation (Save method in controller has [FormValidator] annotation)
Second one (calls another controlers' method) should have validation disabled (Save method in controller has no validation annotation)
At this moment both buttons do POST call to Save method so validation run in both cases. If I remove FormHelper validation tags, client calls correct methods but there is no validation off course.
What should I do in order to enable validation only for one button?
View:
<form id="myFrom" asp-controller="MyController" asp-action="Save" method="post" asp-formhelper="true">
<label asp-for="MyField" class="form-label">My field: </label>
<input asp-for="MyField" class="form-control"/>
<span asp-validation-for="MyField" class="text-danger"></span>
<input type="submit" value="POST with validation">
<input type="submit" asp-controller="MyController" asp-action="AnotherAction" value="Post without validation">
</form>
Controller:
public class MyController
{
[HttpPost, FormValidator]
public async Task<IActionResult> Save(MyViewModel vm)
{
//do sth
}
[HttpPost]
public async Task<IActionResult> AnotherAction(MyViewModel vm)
{
//do another actions
}
}

Calling post method from another controller's view

Problem: Hi there, so in a view where a product is displayed I have a button to call post method to add this product in the cart but the button does not do it at all.
<div class="mb-3">
<input class="btn btn-primary" type="submit" value="Add to cart" asp-controller="Cart" asp-action="Add" asp-route-id="#Model.Id"/>
</div>
And this is the method in the cart's controller
[HttpPost]
public async Task<IActionResult> Add(int productId)
{
//Console.WriteLine("HelloCartAdd!");
//Some logic.
return RedirectToAction("Detail", "Product", productId);
}
When the route parameter is defined as asp-route-id="#Model.Id" the action method should use 'id' parameter name:
[HttpPost]
public async Task<IActionResult> Add(int id)
{
...
}
If the [HttpPost] attribute is applied to the action method add the formmethod="post" attribute to the <input> tag. I suppose the button is already located inside the form.
<form>
<input class="btn btn-primary" type="submit" formmethod="post" value="Add to cart" asp-controller="Cart" asp-action="Add" asp-route-id="#Model.Id" />
</form>

FormCollection is not getting passed to the controller

I can post elements from my form if I make a direct reference to the named element in the controller parameters. I am trying to use FormCollection so I do not have to type every element from the form in the post ActionResult parameters.
The HTML form:
#using (Html.BeginForm("legallabels", "Reports", FormMethod.Post, new { id = "reportForm", #class = "report-form col-9" }))
{
<div class="col-12">
<b>Beginning </b><input type="text" class="form-control col-2" id="beginningDatePicker" name="beginningDate" value="#DateTime.Today.Date.ToString("MM/dd/yyyy")" />
</div>
<input type="submit" value="submit">
}
Controller using named parameter (beginningDate):
[HttpPost]
public ActionResult LegalLabels(string beginningDate)
{
return View();
}
When using FormCollection, it does not get passed to the controller:
[HttpPost]
public ActionResult LegalLabels(FormCollection form)
{
return View();
}
Using a breakpoint in the controller, I can see that the form is posting correctly and everything works fine when naming form elements (beginningDate) in the parameters. I've looked at similar samples of code that use FormCollection and they seem to work fine. Why are my FormCollection values not getting passed to the controller?
Tested your code, it works fine. If you see the snippet below you can loop through all posted values and check.
[HttpPost]
public ActionResult LegalLabels(FormCollection form)
{
StringBuilder sb = new StringBuilder();
foreach (var key in form.AllKeys)
{
sb.AppendLine(string.Format("Key: {0}. Value: {1}.<br>", key, form[key]));
}
ViewBag.FormData = sb.ToString();
return View();
}
On the cshtml
<div>
#Html.Raw(ViewBag.FormData)
</div>
After renaming FormCollection to IFormCollection, everything is working properly.

Changing mvc form controller on submit

I recently came upon this question as I have a solution I need to work on.
I have a controller which does some logic, with some method:
public Controller1: MvcController
{
public ActionResult SomeLogic(Model model)
{
return view();
}
public ActionResult SomeLogic2(Model model)
{
return view();
}
}
And I have a second controller which does different logic:
public Controller2: MvcController
{
public ActionResult SomeLogic(Model model)
{
return view();
}
public ActionResult SomeLogic2(Model model)
{
return view();
}
}
Both are working on the same view:
MyView.cshtml
The view contains a begin form that works on submit:
#using(Html.BeginForm("SomeLogic", "Controller1", FormMethod.Post)
and 4 submit buttons:
<input type='submit' formaction='SomeLogic' value='submit' />
<input type='submit' formaction='SomeLogic2' value='submit2' />
<input type='submit' formaction='SomeLogic' value='submit3' />
<input type='submit' formaction='SomeLogic2' value='submit4' />
I know I can control the action to which I am redirecting the submit using the:
formaction attribute.
I there a way to change the controller as well? meaning that:
<input type='submit' formaction='SomeLogic' value='submit3' />
<input type='submit' formaction='SomeLogic2' value='submit4' />
Will submit to controller2 instead of Controller1 which is defined in my begin form.
This will solve my debate whether to create a new controller or use the existing one, which is already full of complex logic.
You need to include controller name in the formaction attribute.
Note that your controller names are not valid, but assuming your have
public FirstController: Controller
{
[HttpPost]
public ActionResult SomeLogic(Model model)
{
return view();
}
}
public SecondController: Controller
{
[HttpPost]
public ActionResult SomeLogic(Model model)
{
return view();
}
}
Then you can post to the correct controller using
// Post to the SomeLogic method of FirstController
<input type="submit" formaction="#Url.Action("SomeLogic", "First")" value="submit" />
// Post to the SomeLogic method of SecondController
<input type="submit" formaction="#Url.Action("SomeLogic", "Second")" value="submit3" />
Just intercept the submit with jQuery
You can add an ID to your form, to be able to select it easily in jQuery
#using(Html.BeginForm("SomeLogic", "Controller1", FormMethod.Post, new { #id = "yourForm" })
Then
$("#yourForm").submit(function(e){
e.preventDefault();
var url1 = '#(Url.Action("SomeLogic1", "SomeController", null, Request.Url.Scheme))';
var url2 = '#(Url.Action("SomeLogic", "SomeController2", null, Request.Url.Scheme))';
//Whatever logic should you do to select which URL you want to POST to
$.ajax({
type: 'POST',
url: url_selected_above,
data: $('#yourForm').serializeArray(),
success: function (xhr, response) {
//...
},
error: function (xhr, response) {
//...
}
});
});
This should work if all the methods expect the same view model.
Alternatively, if you do not want to mess around in the UI, you can do something as such in the action that generates the form.
var controllerName = "SomeController";
var actionName = "Action1";
//do your logic to select whichever controller/action.
viewModel.ControllerName = controllerName;
viewModel.ActionName = actionName;
And in the view that has the form:
#using(Html.BeginForm(#Model.ActionName, #Model.ControllerName, FormMethod.Post)
Again, if all the actions expect the same view model, that should work.

Post back view values to controller MV3

I am new to mvc 3. i am trying to create a view and controller. my scenario is that i have controller which has two actions. while i call first action inside controller i have to load default values to view. inside view i have a buttons to post back values. so while click one of the button inside view, it has to go second action in same controller and has to return back to same view with success or failure message.
My view is like this
#using (Html.BeginForm())
{
<table>
<tr>
<td>
#Html.TextBox("txtTitle")
</td>
<td>
<input type="button" value="Go Somewhere Else" onclick="location.href='#Url.Action("Postback", "Default1")'" />
</td>
</tr>
</table>
}
My Controller,
public class Default1Controller : Controller
{
//
// GET: /Default1/
public ActionResult Index()
{
// has to default load value to text box
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Postback(FormCollection obj)
{
// has to take value from txt box
object obj1 = Request["txtTitle"];
return View("Index");
}
}
My problem if call Postback action from any other view it works. but inside same view if i click on button the error shows like "http://localhost:14953/Default1/Postback".
What is solution here? i expect to navigate to same controller as well as to other controller inside same form and return to same view.
As reference to this article.....
public class HttpParamActionAttribute : ActionNameSelectorAttribute {
public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo) {
if (actionName.Equals(methodInfo.Name, StringComparison.InvariantCultureIgnoreCase))
return true;
if (!actionName.Equals("Action", StringComparison.InvariantCultureIgnoreCase))
return false;
var request = controllerContext.RequestContext.HttpContext.Request;
return request[methodInfo.Name] != null;
}
}
In view form like this...
#using (Html.BeginForm("Action", "Post")) {
<!— …form fields… -->
<input type="submit" name="SaveDraft" value="Save Draft" />
<input type="submit" name="Publish" value="Publish" />
}
and actions in controller...
public class PostController : Controller {
[HttpParamAction]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveDraft(…) {
//…
}
[HttpParamAction]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Publish(…) {
//…
}
}
You can specify an ActionName to your Postback method like this:
[ActionName("Index")]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Postback(FormCollection obj)...
So F5 repost the same values and calling the URL directly from the address bar returns the View as expected.
There is a constructor for Html.BeginForm Helper method which takes action name and controller name. Use that
public static MvcForm BeginForm(
this HtmlHelper htmlHelper,
string actionName,
string controllerName
)
http://msdn.microsoft.com/en-us/library/dd492590.aspx
So your form should look like this. You dont need the onclick function in your input element.
#using (Html.BeginForm("Postback", "Default1"))
{
//Your elements
<input type="button" value="Go Somewhere Else" />
}
That will render the HTML markup like this
<form action="/Default1/Postback" method="post">
// Your elements
<input type="button" value="Go Somewhere Else" />
</form>
If you want multiple submit button in the same form, It is answered here
I think we can specific action and controller at Html helper.
#using (Html.BeginForm("Postback", "Default1"))
{
<table>
<tr>
<td>
#Html.TextBox("txtTitle")
</td>
<td>
<input type="submit" value="Go Somewhere Else" />
<!-- the input should be submit?-->
</td>
</tr>

Categories

Resources