ASP.NET MVC form post parameter - asp.net-mvc

I have a form in MVC:
<% using (Html.BeginForm("Get", "Person"))
{ %>
<%= Html.TextBox("person_id")%>
<input type="submit" value="Get Person" />
<% } %>
This redirects me to Person/Get. Okay. The question:
How do I make this Form so it redirects me to Person/Get/{person_id}?
Edit:
<% using (Html.BeginForm("Get", "Person", new { id = ??? }))
{ %>
<%= Html.TextBox("person_id")%>
<input type="submit" value="Get Person" />
<% } %>
What do I write in ???

I think the most difficult way would be using a javascript clientside.
The more straightforward way is to retrieve it on the action Person/Get and from there return a RedirectResult pointing to Person/Get/{person_id}
[HttpPost]
public ActionResult Get(string person_id)
{
return RedirectToAction("Get", "Person", new { id = person_id });
}
[HttpGet]
public ActionResult Get(string id)
{
//Do your thing
}
The redirect is usually so fast that the user will never notice. He/she will arrive at /Person/Get/{person_id}

What you want to do is specify the route values as the third parameter on the BeginForm method.
<% using (Html.BeginForm("Get", "Person", **new { person_id = this.Model}**))
{ %>
<%= Html.TextBox("person_id")%>
<input type="submit" value="Get Person" />
<% } %>
Then your controller action would look something like this
public ActionResult Get(int person_id)
{
return View(person_id);
}

Related

How do I post two instances of the same property from a view to an action?

How can I send my data from form, two fields are the same: Station name, but they have different values. How send they via post method to controller. Asp.net mvc2
here what i try:
<% using (Html.BeginForm("ViewRes", "Shedule"))
{%>
<%= Html.ValidationSummary(true) %>
<fieldset>
<legend>Поиск по расписанию:</legend>
<ul>
<li>Из<%= Html.EditorFor(model => model.StationName) %></li>
<li>В<%= Html.EditorFor(model1 => model1.StationName) %></li>
<li>Дата отправления</li>
</ul>
<p>
<input type="submit" value="OK" />
</p>
</fieldset>
<% } %>
and such controller:
[HttpPost]
public ActionResult ViewRes(string a1, string b1)
{
DateTime dtm = Convert.ToDateTime("30.11.2011 0:00:00");
var res = (from d in db.RouteDetail
from m in db.RouteDetail
lalala
where (d.Station == a1
&&
m.Station == b1)
lalalal
}).ToList();
return View(res);
}
The way I would approach this is to refactor my model to encompass both of your existing inputs separately. That way each can be bound accordingly in the action.
public class RailwayRoute
{
public string StartStation { get; set; }
public string EndStation { get; set; }
}
View
<% using (Html.BeginForm("ViewRes", "Shedule"))
{%>
<%= Html.ValidationSummary(true) %>
<fieldset>
<legend>Поиск по расписанию:</legend>
<ul>
<li>Из<%= Html.EditorFor(model => model.StartStation) %></li>
<li>В<%= Html.EditorFor(model => model.EndStation) %></li>
<li>Дата отправления</li>
</ul>
<p>
<input type="submit" value="OK" />
</p>
</fieldset>
<% } %>
Controller/Action
[HttpPost]
public ActionResult ViewRes(string startStation, string endStation)
{
...
}
Expanding on tvanfosson's answer which pretty much sums up, I would try and decouple your data model from your view data. This is often done by using the MVVMC aproach where VM stands for view model. In your case you appear to be passing directly the data model to the view which is sometimes not the recommended approach.
So changing tvanfosson's RailwayRoute to a viewModel object I would ensure the controller action maps the data appropiately. Something like
[HttpPost]
public ActionResult ViewRes(RailwayRouteViewModel viewModel)
{
DateTime dtm = Convert.ToDateTime("30.11.2011 0:00:00");
var res = (from d in db.RouteDetail
from m in db.RouteDetail
lalala
where (d.Station == viewModel.StartStation
&&
m.Station == viewModel.EndStation)
lalalal
select new RailywayRouteViewModel()
{
StartStation = d.Station,
EndStation = m.Station
}
}).ToList();
return View(res);
}

Return a generic list to the MVC Controller

I have a class that looks like this;
public class item
{
public string Tradingname { get; set; }
}
I have a Partial View that inherits from the "item" class;
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<item>" %>
<%= Html.TextBoxFor(x => x.Tradingname) %>
In my view I create a number of them. Let's Say 2;
<% using (Html.BeginForm())
{ %>
<% Html.RenderPartial("TradingName", new Binding.Models.item()); %><br />
<% Html.RenderPartial("TradingName", new Binding.Models.item()); %><br />
<input type="submit" />
<%} %>
Then in my controller I was hoping to be able to write this;
[HttpPost]
public ActionResult Index(List<item> items)
or
[HttpPost]
public ActionResult Index([Bind(Prefix = "Tradingname")]List<item> items)
But I can't seem to get any data back from my partial views into my List. Anyone know how I can get a variable list of data back from a variable set of partialViews?
I would recommend you using editor templates:
Controller:
public class HomeController: Controller
{
public ActionResult Index()
{
List<item> model = ...
return View(model);
}
[HttpPost]
public ActionResult Index(List<item> items)
{
...
}
}
and in the view:
<% using (Html.BeginForm()) { %>
<%= Html.EditorForModel();
<input type="submit" />
<% } %>
and finally simply move the partial in ~/Views/Home/EditorTemplates/item.ascx (name and location are important):
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<item>" %>
<%= Html.TextBoxFor(x => x.Tradingname) %><br/>

How do I create a httppost getting same parameters from httpget?

I have a controller to show up a model (User) and want to create a screen just with a button to activate. I don't want fields in the form. I already have the id in the url. How can I accomplish this?
Use [ActionName] attribute - this way you can have the URLs seemingly point to the same location but perform different actions depending on the HTTP method:
[ActionName("Index"), HttpGet]
public ActionResult IndexGet(int id) { ... }
[ActionName("Index"), HttpPost]
public ActionResult IndexPost(int id) { ... }
Alternatively you can check the HTTP method in code:
public ActionResult Index(int id)
{
if (string.Equals(this.HttpContext.Request.HttpMethod, "POST", StringComparison.OrdinalIgnoreCase))
{ ... }
}
A bit late to the party on this but I found an easier solution to what I think is a fairly common use-case where you prompt on GET ("are you sure you want to blah blah blah?") and then act on POST using the same argument(s).
The solution: use optional parameters. No need for any hidden fields and such.
Note: I only tested this in MVC3.
public ActionResult ActivateUser(int id)
{
return View();
}
[HttpPost]
public ActionResult ActivateUser(int id, string unusedValue = "")
{
if (FunctionToActivateUserWorked(id))
{
RedirectToAction("NextAction");
}
return View();
}
On a final note, you can't use string.Empty in place of "" because it must be a compile-time constant. And it's a great place to put funny comments for someone else to find :)
You could use a hidden field inside the form:
<% using (Html.BeginForm()) { %>
<%= Html.HiddenFor(x => x.Id) %>
<input type="submit" value="OK" />
<% } %>
or pass it in the action of the form:
<% using (Html.BeginForm("index", "home",
new { id = RouteData.Values["id"] }, FormMethod.Post)) { %>
<input type="submit" value="OK" />
<% } %>
My approach is not to add an unused parameter as that seems like it would cause confusion, and is in general bad practice. Instead, what I do is append "Post" to my action name:
public ActionResult UpdateUser(int id)
{
return View();
}
[HttpPost]
public ActionResult UpdateUserPost(int id)
{
// Do work here
RedirectToAction("ViewCustomer", new { customerID : id });
}
The easiest way for such simple situation is to give a name to submit button and check in action if it has value or not.
If it has the value, then it Post action, if not, then it Get action :
<% using (Html.BeginForm("index", "home",
new { id = RouteData.Values["id"] }, FormMethod.Post)) { %>
<input type="submit" value="OK" name="btnActivate" />
<% } %>
For Cs you can combine get and post controller methods in one:
public ActionResult Index(int? id, string btnActivate)
{
if (!string.IsNullOrEmpty(btnActivate))
{
Activate(id.Value);
return RedirectToAction("NextAction");
}
return View();
}

ASP.NET MVC 2 edit controller doesn't work using viewmodel

Hey, the problem is that edit controller in ASP.NET MVC 2 doesn't work. I tried many ways and nothing works.
Here's a sample code:
[Authorize]
public ActionResult Edit() {
var edit = new UserViewModel {
User = Database.Users.Single(u => u.UserName == User.Identity.Name)
};
return View(edit);
}
[Authorize]
[HttpPost]
public ActionResult Edit(FormCollection formCollection) {
var edit = new UserViewModel {
User = Database.Users.Single(u => u.UserName == User.Identity.Name)
};
// TODO: try, catch
UpdateModel(edit, "User");
Database.SaveChanges();
return View(edit);
}
Here's a view model class:
public class UserViewModel {
public User User { get; set; }
}
What should I do to update this user model to database? A the moment I'm using only Email field:
<% Html.EnableClientValidation(); %>
<% using (Html.BeginForm()) {%>
<div>
<div class="UserFieldLeft"><%: Html.LabelFor(model => model.User.Email) %></div>
<div class="UserFieldRight"><%: Html.TextBoxFor(model => model.User.Email, new { style="width: 200px" }) %></div>
<div class="UserFieldHelper"><%: Html.ValidationMessageFor(model => model.User.Email) %></div>
<p><input class="UserFieldInput" type="submit" value="Zmień email" /></p>
</div>
<% } %>
If I work on native user model it doesn't work too. What's wrong? Where did I made a mistake?
By the way, I've to use view model to add (in future) some checkboxes (hair color, length, etc.) to my user.
Thank you for your time and help.
You don't need the prefix "User".
UpdateModel(edit);
should work. In the formsCollection their should be a key with User.Email. This should map to the Email property in the User Object.

How to bind list to a controller

How to bind a list to a controller?
Code in my controller, HTTPGET and HTTPPOST :
public ActionResult Client(string id)
{
List<Customer> Contacts = WebService.GetContactsOfClient(id);
return View(Contacts);
}
[HttpPost]
public ActionResult Client(List<Customer> custs)
{
// custs = null!!! Why??
return View();
}
Code in my view :
<% using (Html.BeginForm("Client", "Formulaire", FormMethod.Post, new { id = "form" })) { %>
<% foreach (var item in Model) { %>
<%:item.MiseAjour %><br />
<% } %>
<input type="submit" />
<% } %>
Thank you all...
If you want to get some values back in your POST action you need to POST them which is achieved using input fields:
<% using (Html.BeginForm() { %>
<%= Html.EditorForModel() %>
<input type="submit" value="OK" />
<% } %>
This outlines what you're trying to achieve.
Model Bind to a List<> when Posting JavaScript Data Object
If you have specific questions, post them
Your view is not rendering any html input elements which are required if you want the model binder to put your model back together on the post. See this answer here which shows binding to a collection and posting to back. Also check out this post for binding to a dynamic list.
Solution for me :
<legend>Contacts</legend>
<% for (int i = 0; i < Model.Contacts.Count; i++) { %>
<%: Html.EditorFor(model => model.Contacts[i],"Contact") %>
<% } %>
With this, I bind my list to controller!
Thank you all!!

Resources