This question already has an answer here:
Posting to a list<modeltype> MVC3
(1 answer)
Closed 12 months ago.
I am creating a wizard and I need to propagate a list that I have created. The list is of my Contact model. I need to put this in the form so that when I post back to the controller on my final step I can have the list of Contacts as part of the wizard model (it just returns null now). For other simple form objects I use a HiddenFor to keep the data in the model. This doesn't work because a hidden for is just a text box and I have a complex object.
I considered creating a DropDownListFor and wrapping it in a hidden div. This is just patchwork and would actually take a bit of work to get DropDownListFor to accept another object type (if it would work at all).
I have considered saving the list to Session["Contacts"], but that does not seem like the proper MVC way to go. Does anyone have any better suggestions?
Thanks,
TJ
--UPDATE--
In response to merekel I am adding more detail to clarify where I am having the issue. This list is not modified by the user and will not display on the form. I create the list in one of my wizard steps and save it to my model like this.
View Model
public class WizardViewModel
{
//...
public List<Contact> ContactList { get; set; }
//...
}
Controller code
//Step 4 in the wizard
model.ContactList = CALL FUNCTION THAT CREATES LIST BASED ON FORM SELECTIONS
//other calculations needed for step 5
//Save Contacts for later
Session["Contacts"] = model.ContactList;
//Step 5 in the wizard
//Readd the contacts to the model
model.ContactList = (List<Contact>)Session["Contacts"];
//Save the model to pass to the report page
//My report viewer is on an ASPX page so I am passing all the data here with a session
Session["ReportModel"] = model;
The session save works as expected. It just does not seem like I should be using sessions to save data from page to page with MVC. I need to when going from MVC to ASPX, so I am not worried about Session["ReportModel"] only Session["Contacts"]. Thank you for any suggestions.
I believe that posts like this will help 1, 2. There are many posts similar to these on how to post back lists.
Are these contacts populated from your form or are they global contacts?
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Well, I am creating this app that allows me to query certain DataBase using ASP.NET MVC 5 with Entity Framework 6.1.3.
Well I came across this situation. I have a DataBase with several connection strings that let me access different databases.
So I want to create a model where the user can create queries upon those databases. So I came up with idea to let the user create it as he/she were creating a question. For instance: Someone would want to know How many students are studying in the faculty {PLACEHOLDER}? where "How many students are studying in the faculty is a LABEL and {PLACEHOLDER} is a COMBOBOX. The ComboBox will be filled with a list of faculties (A query to a table of a database).
My idea is provide the user with links in order to add as many Labels, TextBoxes, ComboBoxes, etc. for him to create the question. If the user were to create the question above he will add a Label, and then a ComboBox. Then he/she will fill the information, and with some other function (i am to develop but not the main goal of this question) will satisfy the query.
So, how can I runtime create a link that add me those (label, textbox, etc.) items in runtime to the view, and then gather that information and save it into the database (for the model in question)?
I´m guessing my link from the view(or viewmodel?) has to pass some information to the controller and then do something and render the view back and let the view know that there is a new "control" (how I named the model for those controls) and render it (or else). How can I achieve that?
Hope I explained myself. If not, please comment and I´ll try to do it better.
Thanks in advance!
You're trying to create dynamic fields, right?
You can add the inputs and selects with JavaScript,then, in your controllers, you can parse as many objects parameters your need.
For example, you can create a new model called "Question", with a defined structure like:
public class Question {
public string Label {get; set;}
public string PlaceHolder {get; set;}
}
And in your controller:
public ActionResult SomeController(Question[] questions)
{
....
The most difficult part is creating the submit data.
I found these links in the SO that can help you with that.
Passing A List Of Objects Into An MVC Controller Method Using jQuery Ajax
MVC Form not able to post List of objects
How to pass array of objects to an MVC Controller in Jquery?
This question already has answers here:
POST a form array without successful
(5 answers)
Closed 7 years ago.
I'm starting with MVC and i have some basic questions that maybe you can orient me a little bit:
I'm Using MVC5 with Razor and EntityFramework 6. No AngularJS skills here.
I have a classic Master-Detail CRUD where i need to create Order and OrderItems. My idea es that when you create the order, you can add the items in the same form and then with one SAVE button create both records on the database (The Order and the Items).
I've created the "Orders" CRUD very good with scaffolding, and it works perfect. But now i need to add to the same VIEW the items, and here is what i'm getting lost and try different ways to do this:
BINDING ISSUE: I thought that probably i could add the list of OrderItems to the binding header on the CREATE event. My OrderController has this method:
public ActionResult Create([Bind(Include = "Id,Date,*other fields*")] Order order) and it works fine with the ORDER CRUD operations. But, now, if need to add a List to the list of fields binded on that header, is that possible? How should i save the data in the View then?
JSON: Another way i thought, was to remove the Binding header and use Json, but all the examples i've seen was using AngularJS and i have all the site done except for this CRUD, i preffer to let that option for the real last chance. On the other hand, i've found this: https://www.youtube.com/watch?v=ir9cMbNQP4w and it's exactly what i need to do, but: It's on MVC4 and not MVC5, and also i have all my entities validation in my model (extended) class and some of them in the controller as well (exclusively the ones related to the Creation or editing the order). Tell me if i'm wrong here please!
PARTIAL VIEW: The last way i've just tried was with Partial View. I've created succesfully the Initial data load based on this tutorial: http://dotnetmentors.com/mvc/render-partialview-with-model.aspx , but after that, i need to add new items to my order, or edit/delete the existing ones and here is where i get lost: Should i have different CREATE/EDIT methods for the partial views? How i send the data then? How i can use only one SAVE button that saves everything at the same time?
I'm getting more lost when i look for more information.... so, here i am asking for help to you guys !
Thanks a lot in advance !!
Create a custom view model:
public class NewOrderViewModel
{
public Order order { get; set; }
public OrderItem[] orderItems { get; set; }
}
Then you can use this in the view by changing #model NewOrderViewModel at the top and you will be able to use like:
#Html.TextBoxFor(m => m.order.Phone);
#Html.TextBoxFor(m => m.orderItems[0].ItemName);
You will need some javascript to copy the html and create new form elements for each new orderItem the user wants to add.
Then your controller signature would look like:
public ActionResult Create(NewOrderViewModel content)
So I'm consuming a RESTFul API to get the data I need. This API returns json and i converted this to C# models. The API returns some general info about a vendor and an array with products. The array of products also consists out of arrays for pricing information and product availability etc...
The problem im facing is that when a product is selected by a user to buy i have to gather specific information out of the different array's. Currently I've made a ViewModel for the data that needs to be send to process the order. This is done by binding the actual data using hidden fields and use a HttpPost from the view, resulting in +/- 30 hidden fields to set the proper data values.
I'm kinda new to MVC and this seems dirty. I thought i would be able to pass the models(for example the VendorModel,ProductModel,PricingModel,AvailabilityModel) from the view(with a POST) to the controller and create the ViewModel(based on the models send) so that i can send that to the API.
Is this actually how it should be done or is my design faulty and should i approach this differently?
A side note: One of the things i found is that most people suggest to use an identifier to get the data you need but the problem is that the API doesn't have the right calls to get Product, Pricing, Availability data based on Id, its just one big object with array's based on the search query.
Edit
So after some information i decided to try out nested models and created a viewmodel like this:
public class TestViewModel
{
public TestViewModel()
{
productInfo = new ProductInfo();
}
public ProductInfo productInfo { get; set; }
}
My view is like this(super simpel):
#using (Html.BeginForm("CreateOrder","Products"))
{
//Vender info etc...
//This is how i render partial view now:
{Html.RenderPartial("Info/ProductInfo", Product.ProductInformation.ProductInfo);}
<input type="submit" value="Order" class="btn btn-default" />
}
My controller(TestViewModel.ProductInfo is always null):
public ActionResult MakeReservation(TestViewModel testViewModel)
{
//Doesnt do anything just debugging TestViewModel
return View();
}
I'm not posting any inputs but just want to pass the modal with the data to the controller. How will MVC know which data to bind, because now it doesnt bind. Do i have to bind it myself somehow?
I had the similar situation and I have one suggestion, you can pass all the models to the view as save in a javascript object as JSON using the example code which I used like below-
<script type="text/javascript">
var pageBlockOptionsJSON = #(Html.Raw(Json.Encode(DesignOrderBlocks)));
var controlTypeJSON = #(Html.Raw(Json.Encode(controlList)));
</script>
Then you can do all the manipulations using jQuery to structure and create a javascript object and post that object to Controller Action. You can create the same or exact structure which is needed on the server. As specified in this url - http://www.nickriggs.com/posts/post-complex-javascript-objects-to-asp-net-mvc-controllers/
In this way you don't need to have use huge amount of hidden fields and you can do all the dirty work on the client side using jQuery.
I am sure this will help you out in doing the thing in the right way. Let me know if you need some details.
For people that somehow find this questions i solved this issue by saving the model to an database as an search result using entity framework. After getting the result i save it and create a viewmodel. After posting i send the id's that entity framework generated and search the right models in the database creating a new postviewmodel.
I'm hoping you guys can answer me a question?
I've only just started out using ASP.NET MVC3 have come unstuck at a certain point. I've been learning this stuff from books and I'm slightly unsure on a few things.
Can a VIEW, only have one #Model reference?
At the moment I have a VIEW setup with a HTTP-POST on a ViewResult, that validates the data in the View, entered by the user and then "on post", passes this info to a method that writes it back to a database(ADO.NET - Access). Now I need to change my VIEW, so that I can replace a couple of my text boxes for Dropdownlistfor controls. The Data to populate these controls will need to be passed in from the Database.
Would I be correct in saying that this data needs to be passed in the HTTP-GET Viewresult of the page, and if so, can i reference more than one #Model in this same View (*.cshtml).
I have a class that takes in the user response, and this is referenced in the View. But will i need to create a new class for the dropdownlist data and reference that too. So that in the background I populate the data into a SelectListItem, pass it to the View and then populate each drop down control within the view?
I'm sorry if this is poorly written, very hard to explain, I find learning from books hard and I'm pretty stuck now. Any help would be appreciated. Just to give me an understanding of how this all wraps around. I'm comfortable with the C# syntax, but very unsure of MVC3!
There are two ways you can handle this.
Use a View Model.
In this scenario you have a class that contains your data model as well as other things required by the view, so something like this:
public class ViewModel
{
public MyDomainModel Model { get; set; }
public IEnumerable<SelectListItem> SelectListItems { get; set; }
}
Use ViewBag.
In this case you add everything extra into the ViewBag dictionary. So in the controller, you'd have stuff like this:
ViewBag.SelectListItems = new SelectListItem[] { ... };
Then you can reference in the view itself
#Html.DropDownList("myselectlist", ViewBag.SelectListItems)
I think that this will help you pluralsight mvc3 intro. It sure helped me
Background
I'm learning the ropes around how to use ASP.NET MVC properly, and ran into this issue with models:
I have a model that describes a contact I can get that out of the form for creating a new contact, but say when we edit a form, I retrieve it from the repository, show the fields on the contact form and then get the contact object and send that to the model.
Problem
I have a business rule that some fields are not allowed to be edited after creation and other fields are only available after editing.
I receive a dirty object from the user (one with fields they should touch) and using the MVC Binding method (sspecifying the object in the method signature) the users inserts a non-editable field contact_dob.
Question
Should I instead retrieve the record again, overwrite only the fields I want to update and then send it to the database?
What's the best method when I don't want to retrieve the Entire object again from the database, do I just redo another EntityModel that's a lighter version of the main model and use that back and forth?
Am I going about this the wrong way? What are the best practices for limiting what users can edit?
I think you can build your model, the Contact class, and in the edit view you should allow only fields that can be edited, and hide or set as not editable the fields you don't want to be edited, then in your controller you'll get the original contact and update it with the values of the fields you allowed in the edit view like:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection formValues) {
Contact contact = repository.GetById(id);
try {
UpdateModel(contact);
repository.Save(contact);
return RedirectToAction("Details", new { id=contact.Id });
}
catch(Exception ex) {
// Do something...
}
return View(contact);
}
It sounds like the best solution would be to use a custom ViewModel. This is an object that contains all the fields that you would want the user to submit to the controller.
You will need to reload the contact object from the database - I don't think you can get around that without opening yourself up to other issues.
public ActionResult Edit(ContactViewModel viewModel)
{
var contact = repository.GetContacts().WithId(viewModel.Id);
// Update the contact with the fields from the viewModel
repository.Save(contact);
}
You should use the EXCLUDE and INCLUDE constraints in Action method. This way your model will exclude unwanted fields during model binding.
public ActionResult Create([Bind(Exclude="contact_dob")] Contact contact)
{
_db.AddToContacts(contact);
_db.SaveChanges();
return RedirectToAction("Index");
}
The 'best practice' is to have validation done against your submitted model and not allow changes to certain fields. You can use JQuery / JavaScript to grey out textboxes that cannot be changed; as well as validation on the Model side to disallow changes to certain fields (by comparing them against what came from the database).
You can use Model Validation to disallow changes to certain fields. ASP.NET MVC 2 has this functionality. You don't even need to re-retrieve the object.
In the 'NerdDinner Walkthrough' (ASP.NET MVC 1.0), there's a walkthrough of Validation.