This is not duplicate thread .
My case is to send array parameter without model. but other thread is send int, string parameter individual.
I know about how to post to controller with model object.
But sometimes I want to post data outside of model db and post in format object or array
How could I do?
View
<form action="/home/showdata" method="post">
<input type="text" name="arr.username" />
<input type="text" name="arr.password" />
<input type="text" name="arr.email" />
</form>
Controller
public class HomeController : Controller
{
[HttpPost]
public ActionResult ShowData(Array data)
{
return Content(data.username + data.password + data.email);
}
}
There are many different kinds of Models. E.g. Database Models, View Models, DTOs etc. So, in your case, the data you receive from the client is significantly different from the database model (which, by the way, is usually the case). This means you should create a model specific to a view, a View Model, then after validating the data, transfer that that data to the database model. For example:
public class SampleViewModel {
public int Id { get; set;}
public string Name { get; set; }
}
And then in your controller:
public IHttpActionResult SampleActionMethod(SampleViewModel model) {
if (!ModelState.IsValid) {
return BadRequest();
}
var sampleDbModel = new SampleDatabaseModel() {
FullName = model.Name,
ProductId = model.Id,
// ... some other properties ...
};
// ... Save the sampleDbModel ...
return Ok(); // .. or Created ...
}
This answers just shows you how to do what you are trying to do. But ideally, you should NOT use database model as parameters to action methods anyway. And there are a lot of other things involved, for which I suggest you look into Repository Pattern, Unit Of Work (for managing database tasks), and Automapper (for mapping stuff, if you want. E.g. view models to models) etc.
Hope this helps.
Hello i would recomended you FormCollection
<form action="/home/showdata" method="post">
<input type="text" name="username" />
<input type="text" name="password" />
<input type="text" name="email" />
</form>
in controller you can use FormCollection
public class HomeController : Controller
{
[HttpPost]
public ActionResult ShowData(FormCollection data)
{
string username=data.GetValues("username")[0];
string password=data.GetValues("password")[0];
string email=data.GetValues("email")[0];
return Content(username + password + email);
}
}
also if some html input has same name then you will get string array of their value.
The best solution here is to use a model. A model does not have to be related to a database table.
public ActionResult ShowData(Array data)
could be:
public ActionResult ShowData(YourModelNameHere data)
And you could define YourModelNameHere as something like:
public class YourModelNameHere
{
public string username {get; set;}
public string password {get; set;}
public string email {get; set;}
}
First you need to serialize your data on form and keep serialize data in hidden filed and after post get this data from formcollection using key and de-serialize
it.
Related
I have a list of teams on my index page.
I'm trying to pass the text of an input(type text) from the index view back to the index controller, to reload the index page, this time only displaying items in my list which have matching text. eg - bob = bob
Index Controller
public ActionResult Index(string searchString)
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
var listOfTeams = from T in db.Teams
select T;
if (!String.IsNullOrEmpty(searchString))
{
listOfTeams = listOfTeams.Where(T => T.TeamName.Contains(searchString));
}
return View(listOfTeams.ToList());
}
How i'm trying to pass the data in the Index view
I've tried
<input type="text" id="inputTeamSearch" name="searchString" class="form-control" style="width:225px;height:60px" onblur="IsTextEmpty()" oninput="CheckTeams()" placeholder="Search">
#Html.ActionLink("Search", "Index")
and
#using(Html.BeginForm("Index", "Team"))
{
<input type="text" id="inputTeamSearch" name="searchString" class="form-control" style="width:225px;height:60px" onblur="IsTextEmpty()" oninput="CheckTeams()" placeholder="Search">
<input type="submit" id="Index" value="Index" />
Html.EndForm();
}
I'm sure this is probably a duplicate of some sort, if so please just pass me in the appropriate direction. I've looked for answers, but they're either long-winded or go into more complex detail than this.
So to post data to a controller you need a seperate post action which is decorated with the HttpPost attribute. This method needs to take a model as it's parameter:
[HttpPost]
Public ActionResult Index(IndexVM model)
{
var searchTerm = model.SearchTerm;
}
The view model needs to contain the fields that you intend to post.
Public class IndexVM
{
Public String SearchTerm { get; set; }
//Other model examples
public Int32 PageNumber { get; set; }
public Int32 NumOfItemsPerPage { get; set; }
}
Then your html needs to contain a text box that has the same name as the string property in your view model.
#Html.TextBoxFor(m => m.SearchTerm)
//And at the top of your html page you will need to include the model
#model Domain.Models.IndexVM
OR
<input type="text" name="SearchTerm">
Should work.
If you are already using an entity model you can create a new View model which contains the old entity and whatever else you need. So:
public class IndexVM
{
public Team Team { get; set; }
public String SearchTerm { get; set; }
}
Then on your index GET method where you're passing your team to your view you would have:
var view = new IndexVM();
view.Team = //your team object
return View(view);
I'm a bit new to MVC, and maybe I'm just misunderstanding something, but I can't figure out how to do the following in an elegant way:
I have the following Entity that I wan't updated:
Model:
public class Entity
{
[Key]
public int Id { get; set; }
public DateTime Created { get; set; }
public int FieldInt { get; set; }
public DateTime FieldDate { get; set; }
public int FieldOther {get; set; }
}
}
View:
My view displays a bunch textlines with checkboxes attached. The checkboxes are identified by two data-attributes: data-field-int and data-field-date, which is something along the following.
#html.BeginForm("Confirm", "Home", FormMethod.Post) {
...
<input type='checkbox' data-field-int="1" data-field-date="2014/01/01" />
<input type='checkbox' data-field-int="1" data-field-date="2014/02/02" />
<input type='checkbox' data-field-int="1" data-field-date="2014/03/03" />
...
<button id="ConfirmButton" type="submit" class="btn btn-primary">Confirm</button>
}
What I want in the controller is when the ConfirmButton is pressed, create an Entity object for each checkbox that is checked with the value of fieldInt and fieldDate populated with data-field-int and data-field-date attributes respectively.
I can do it by making the controller action take FormCollection as input and by putting a name attribute on the checkboxes with a concatenation of fieldInt and fieldDate and then seperating them in the controller and updating the db. But it seems like there would be a better way, since MVC is so smart with Entity Framework.
I hope you guys can help me understand
Thank you,
Peter
welcome to MVC .
-Using razor engine with model entities is the best practice.
-In the above mentioned code you need to set something like this
#using ( Html.BeginForm("Confirm", "Home", FormMethod.Post))
-As you are new try using strongly typed views with selected templates which generates razor code for you i.e you can analyse deep
-Finally just use model x as parameter to you [HttpPost] action method and convert these entities to you Entity framework entities and save in DB
Additionally :
Data attributes are not included in the data that's posted with the form, so there is no way to read them in your controller action. Try using a hidden field instead
Like
#Html.HiddenFor(m => m.FieldInt) or
<input type="hidden" name="FieldInt" value="1234" />//do similarly for rest
Passing static then #{Model.phoneno = "1234"}
This question consists of two parts:
1.
It is good to specify #model in razor view and use helper methods that take lambda expressions with the model as parameter.
#model MyType
html.Textbox(model => model.FieldOther,...)
Then you create action that takes the model
[HttpPost]
ActionResult MyAction(MyModel model) {
....
}
Mvc will try to create instance of the model and map form fields to the model properties.
2.
You can use entity as model but, believe me, so called Data transfer Objects and/or View Models were created for a reason and as application evolves, single views evolve too to manipulate data from many related database entities.
I'm working on a school project and I need some help.
I've created a form and I want to get the submitted values from it.
Is it possible to do this without using JavaScript?
And in that case, how do I do it?
Form:
<div id="secondRowInputBox">
<% using (Html.BeginForm("Index","Home",FormMethod.Post))
{%>
<%= Html.TextBox("Id")%> <br />
<%= Html.TextBox("CustomerCode") %><br />
<%= Html.TextBox("Amount") %><br />
<input type="submit" value="Submit customer data" />
<%} %>
</div>
Just create an HttpPost action in your controller accepting the form values as parameters:
[HttpPost]
public ActionResult Index(int id, string customerCode, int amount)
{
// You can change the type of the parameters according to the input in the form.
// Process data.
}
You might want to look into model binding. This allows you to create strongly-typed views and saves you the trouble of creating actions with dozens of parameters.
You have already done half the work, now in home controller make an actionresult
[HttpPost]
public ActionResult Index(int id, string customerCode, int amount)
{
// work here.
}
form post method will call this method, as you have specified it in the begin form parameters.
It will be better if you use a model for passing values and use it in view for form elements
[HttpPost]
public ActionResult Index(ModelName modelinstance)
{
// work here.
}
Sample loginModel
public class LoginModel
{
[Required]
[Display(Name = "Username:")]
public String UserName { get; set; }
[Required]
[Display(Name = "Password:")]
[DataType(DataType.Password)]
public String Password { get; set; }
}
now if was using this login model in the form
then for the controller action, modelinstance is simply the object of model class
[HttpPost]
public ActionResult Index(LoginModel loginDetails)
{
// work here.
}
if you have a lot of variables in the form then having a model helps as you don't need to write for all the properties.
Henk Mollema's answer is good. Here to say something more on it.
Html.TextBox will generate html like below one, there's a name attribute.
<input id="CustomerCode" name="CustomerCode" type="text">
When you submit the form, all the values of input fields can be get from Request.Form by name attribute as key Request.Form["CustomerCode"], and ASP.NET MVC has done some magic for us, so it can simply go into the param of the action method.
Without customization, can I do something like this in MVC 3?
[HttpGet]
public ViewResult MyAction(ViewModel model)
{
// Do stuff
return View("ViewName", model);
}
The reason I am doing this is to pass data between different pages as part of a work flow. (I.e. when user fnishes what's needed in step 1, pass the form data to step 2...)
It will work as long as you have the same parameter Name as of the Property name of your Model class
Assuming your class is like this
public class ViewModel
{
public string Name { set;get;}
public string Loc{ set;get;}
}
You can do a Get request like this
MyAction?Name=jon&Loc=America
Shyju's answer only works if the members of class in the endpoint's method signature contains only scalar properties. But what if you have nested classes? Let's assume that your ViewModel class looks like this:
public class ViewModel
{
public string Name { get; set; }
public string Title { get; set; }
public Address MyAddress { get; set; }
}
And the Address class looks like this:
public class Address
{
public string Line1 { get; set; }
public string Line2 { get; set; }
}
Now let's say the GET request was done via AJAX and you did something like this in JavaScript:
var address = {
Line1: "123 Nowhere St.",
Line2: "Apt. B5"
}
var getRequestData = {
Name: "Joe",
Title: "Manager",
MyAddress: address
}
var uriString = $.param(getRequestData); //the parameters for the GET request
$.get("/ViewResult?" + uriString, function (data) { /*callback function*/ });
Even though the shape of your address object in JavaScript perfectly matches the C# Address class in the endpoint's method signature, the Line1 and Line2 sub-properties will NOT bind. Their values will come through as null.
There are two workarounds to this.
Workaround 1:
The first is to use dot notation when naming the parameters in the GET request instead of nested JavaScript objects. Using this method, the GET request data in AJAX would look like this:
var getRequestData = {
Name: "Joe",
Title: "Manager",
MyAddress.Line1: "123 Nowhere St.",
MyAddress.Line2: "Apt. B5"
}
MVC model binding will know how to do this, as long as all your property names all match up (they are case-sensitive, so be careful).
If you're not using AJAX, but just a plain HTML form submit, it's even easier. Just name the input elements with that same dot notation. Razor syntax makes this really easy with helper methods like TextBoxFor(), but here's an example in plain HTML:
<form method="get" action="/ViewResult">
<input type="text" name="Name" />
<input type="text" name="Title" />
<input type="text" name="MyAddress.Line1" />
<input type="text" name="MyAddress.Line2" />
<button type="submit">Submit GET request</button>
</form>
Workaround 2:
The other way around this is to simply use a POST request instead of a GET. Beware that it's technically bad practice to perform a POST request without the intent of actually changing some data on the server side, but it is an option.
You can do it; it will automatically bind any values in the query string to properties with matching names.
That said, it's not something that's generally done; it's the [HttpPost] method where you see the model binding performed, as the interfaces for the two actions need to be different somehow. You can solve that by posting back to a different action name, but you may still trigger model validation errors on the (partial) load of the model, which would be really confusing to a user.
For Web API 2:
[HttpGet]
public ActionResult Get([FromUri]ViewModel model)
{
// Do stuff
return View("ViewName", model);
}
You can post a form to a get by setting the PostMethod attribute to get. If the form's input fields match any of the accepting ViewModel then they will be filled. These matches are determined by the name field in an input (<input name="MatchedField"> -> public string MatchedField { get; set; }).
What you should do is pass the form from a post, and then redirect to the get from the post action. This pattern is best practice and is known as the Post-Redirect-Get pattern.
I would advise against this approach. Best solution to just use POST, because if you use GET, once you click back from step 3 to step 2 and the browser cache is not available, you will perform actions on an old version of the ViewModel. Is there a particular reason why you want to use GET?
I can not suggest to use QueryString to pass values.
You can use one of below:
This code will render a partial view with the given model.Be sure you add model to your view. And your view should be placed in Shared folder
public ActionResult myaction(ViewModel model)
{
return PartialView("anotherView", model);
}
Another way to do almost the same thing:
public ActionResult myaction(ViewModel model)
{
return View("someAnotherView", model);
}
if your view is not in the same controller , use the path for view name like "../Controller/viewName"
There is also a different approach which can be done by using TempData:
public ActionResult myaction(ViewModel model)
{
TempData["model"] = model;
return RedirectToAction("someAnotherView");
}
but you should reach your data in the view with the code as shown below:
#{
ViewModel model=(ViewModel)TempData["model"];
}
Hope one of above helps..
Regards
I am developing an ASP.NET MVC 3 application in C# and I use Razor. I am now dealing with a problem concerning the binding of objects through ViewModels passed/received to/from the View by the Controller.
Let's make it clear. I have the following ViewModels:
public class ContainerViewModel
{
public int ContainerId {get; set;}
public string ContainerName {get; set;}
public List<ItemPostModel> ItemData {get; set;}
}
public class ItemPostModel
{
public int ItemId {get; set;}
public string ItemName {get; set;}
public int ItemValue {get; set;}
}
The ContainerViewModel is used to pass the data to the View. Its properties ContainerId and ContainerName are used just for display purposes. The List<ItemPostModel> property has to be filled using a Form. The View looks something like this (it is a simplified version):
<strong>#Model.ContainerName</strong>
#using (Html.BeginForm())
{
<fieldset>
#foreach(var item in Model.ItemData)
{
#Html.TextBox(item.ItemId);
#Html.TextBox(item.ItemName);
#Html.TextBox(item.ItemValue);
<p>
<input type="submit" value="Save" />
</p>
}
</fieldset>
}
The Controller corresponding action methods are as follows:
public ActionResult UpdateItems()
{
//fill in the ContainerViewModel lcontainer
return View("UpdateItems", lcontainer);
}
[HttpPost]
public ActionResult UpdateItems(int containerId, ItemPostModel itemData)
{
//store itemData into repository
}
The problem is that with this code the ItemPostModel itemData passed to the Post ActionMethod UpdateItems is always empty. The containerId is correctly passed. Same result if I use the following code in the Controller (obviously not DRY);
[HttpPost]
public ActionResult UpdateItems(ContainerViewModel container)
{
//extract itemData from ContainerViewModel container
//store itemData into repository
}
How can I "teach" the application that I want the form elements stored in the List<ItemPostModel>? Shall I modify the ModelBinder or there is a simpler way to perform this task? Thanks everybody for your answers.
Don't write loops in a view. Use editor templates:
<strong>#Model.ContainerName</strong>
#using (Html.BeginForm())
{
<fieldset>
#Html.EditorFor(x => x.ItemData)
<input type="submit" value="Save" />
</fieldset>
}
and inside the corresponding editor template (~/Views/Shared/EditorTemplates/ItemPostModel.cshtml):
#model ItemPostModel
#Html.TextBox(x => x.ItemId)
#Html.TextBox(x => x.ItemName)
#Html.TextBox(x => x.ItemValue)
And in the controller action you might need to specify the prefix:
[HttpPost]
public ActionResult UpdateItems(
int containerId,
[Bind(Prefix = "ItemData")]ItemPostModel itemData
)
{
//store itemData into repository
}
and that should be pretty much all. The editor template will take care of generating the proper input field names for the binding to work.