ASP.NET MVC3 model with list - asp.net-mvc

I have a minor problem in MVC 3. I'm creating an application, where my model, a shipment, consists of the following:
a user id (string, required)
a reference id (string, optional)
a list of order ids (strings, cannot be empty)
The index view of the application is where the user creates the shipment (model). Once this is done, the user has no further interaction with it (no edit, detail or list views).
My problem is this. I'm trying to use one form for both adding order ids, and for creating the shipment itself, using two separate buttons for submitting ("Add" for adding order ids, "Send" for creating the shipment). It seems that when I'm using the Create-action of my controller, that pressing "Send" overwrites my list of order ids with an empty one. However, if I'm submitting to the Index-action, and redirecting to Create on a press of "Send", my model validation is gone (ModelState only contains "submit").
Right now I'm using sessions to pass data around my controller actions, which is probably not the best way to do it.
TLDR; I need a way to add items to a list in a model, one at a time, while persisting other form data, and still be able to validate it.
Any suggestions?

It's better to take a look on your Actions, because it's not quite clear what are you doing there, but still it looks like you are tring to use same data structure to pass different tipes of parameters (one contains list, another contains general data). I think it's better to submit different data structures and build required result data object in each action.

Related

Partial Page Postback'ish MVC 4

First, I apologize if this is a dumb question, but I'm new to MVC and am trying to get up to speed as quickly as possible. I have spent hours searching for answers and even went and bought a book on MVC 4, but it still didn't answer my question.
I have a form I'd like a user to fill out to add a new product to the catalog. They choose the category, enter the name, a description, etc.. On the same page I'd like them to be able to add sizes or product options such as Small, Medium, Large, etc.. The problem is I'm not sure how to go about this.
I need to temporarily store the size options for example in some sort of collection until the user actually 'saves' the product, then I need to be able to read the collection. What I'm trying to avoid is to have the user add the basic product info, then save it, then select it, then choose to add options to it. I'm trying to just do it all on one form. Any help would be greatly appreciated!
There is nothing preventing you creating a view model with its own collections for the detail items and have those mapped to some sort of javascript control for selecting multiple items such as one that writes to an mvc hidden form control.
The controller handling the postback will simply create the master model from the postback data (the updated view model) and then create the child records. The whole thing could be achieved with ajax calling a controller action that returns a partial view of the updated ui.
Similar to this but have the list as a property of the master model
http://www.stevefenton.co.uk/Content/Blog/Date/201002/Blog/How-To-Handle-Multiple-Select-Lists-In-ASP-NET-MVC/
A little more advanced on how to manage your own bindings http://www.dotnetcurry.com/ShowArticle.aspx?ID=584
Sounds like u need to roll your sleeves up and get a control written in javascript that allows child items to be added client side whist serializing e.g. Into json when they save and saving it to an mvc hidden control ready for postback. Use json.net to hydrate these values into your pocos. http://erraticdev.blogspot.co.uk/2010/12/sending-complex-json-objects-to-aspnet.html

Telerik Grid MVC and check all checkbox on all pages

On Telerik demo site we can see an example of how to implement kind of functionality: "check all checkbox in a grid's column". But in my case it has 2 disadvantages:
It didn't check all checkbox on all pages.
It didn't save a state of checkboxes on different pages.
Is anybody know how to resolve these issues? Thanks in advance.
As long as I know there's no built-in functionality to do so. The same problem happens when you select records on page one and change to page two, you loose whatever you selected before.
To achieve that functionality you have 2 options (I've used both on previous projects)
1) On each check make an Ajax call to one of your controllers and store whatever you selected on a Session Variable (This can be inefficient if you have a lot of records)
2) Create a javascript variable and store your selections there, and send back to the controller using a json variable or a comma separated values string
As I said, I've used both approachs so it depends on if this works for you or not
Hope it helps
I can't test this, so I'm not 100% sure, but looking at Telerik's example, one reason it's not persisted is because every "page" of the grid requires a postback, and in the controller action result method, they aren't passing in the model (or view model) for the items that are bound to the grid, they're only returning that list of items back to the view, so it will never "save" which items are checked/selected and which ones aren't. You should be able to get around this by making your view model a parameter into the HttpPost action result method and then passing that list back to the view after the post so that it retains which items are selected instead of creating a new one. This won't solve the issue with not selecting all the items, but it should at least retain which ones are selected throughout the pages. I think the reason for it not working with all items is it can only select the ones that are actually being displayed at the time. You may want to do a post (or ajax) to select "all" items.
One of the major reasons for using paging in grids is so that you don't have to retrieve all of the data from the data store and generate a lot of HTML to push to the client.
It's been my experience that most users understand that a "select all" check box only checks the items on the current page. I've not seen a site where checking such a check box would actually check all records, even those I can't see.
If you have an action which will affect more than the current page of records, I would suggest that you add a button which clearly indicates that the action will affect all records, then send a command to your data layer which will perform that action. This will perform better (you don't have to send a potentially long list of ids across the wire) and allow users to understand the repercussions of their action.

shortterm storage of user selection from form to controller

I am trying to conceive of a way to store a list of selected items to the session, for later use. I've googled and read examples for 2 hours now, and haven't found any examples that work.
The basic idea is this. User sees a list of items to act upon. User selects a number of them. User chooses action to perform. Controller takes list of selected items, and begins to act on them.
Am I thinking about this wrong? It makes sense to me to use an Ajax action to store the 'select/unselect' action on the session object. I really don't want an entire database object to handle this. I just want a simple list of selected objects. In classic ASP, I'd just have reacted to the selected items in a form post, but that doesn't seem right in asp.net mvc....
How do I construct this behavior (with or without the Ajax, but preferable without the DB access)?
I don't get it, why not bind directly an array of bools or something directly to your view's list of checkboxes? You can get them as parameters in your controller function and act upon them directly, with no middleman, they'd just be another POST value.
Or even better when you send in your list of items as part of your model, make them a structure that has a bool selected=false field that is bound to the checkbox next to the label, and you'll get the results back in your model directly.

Displaying and updating multiple models in one view

I have 3 different models, business_info, business_hours, business_vacations.
I have one view that displays all that information, so I made a new controller called business_all to gather all that info.
But when it comes to editing the individual parts within the page I'll be calling each of those 3 individual controllers to update, delete etc, then send back the updated data for that particular model.
Given that, should I skip having the business_all controller and instead, when the view is loaded have 3 ajax calls to each controller to get the relevant info?
one alternative is to make a non persisting model called business_all that has fields that combine the three models with its own validation and so on. and when persisting it actually saves to the actual models.
this way doing the forms and so on are easier as you can do form_for (BusinessAll.new ... ...) and so on.

How to send data generated from one http post to a second http post in ASP.NET MVC?

I have a view that is being used to create an invoice. The process should be as follows:
1. The user specifies a customer from a drop down and then a start date and end date.
2. They then click on a submit button, which is linked to the controller. This then builds an IList of all the jobs that meet the above criteria.
3. The page refreshes and displays the list of jobs.
4. On the same page, there is a second form which asks for an "Invoice Date" with another submit button. Clicking this should then Update an Invoice table in my DB whilst also looping through the IList of jobs and attaching invoice ID's to them (which are stored in another table in my DB).
The issue I'm having is that I've built a method which accepts the invoice data and the IList of jobs, but when I try to pass over the IList on the second submit controller method, it's null.
In the above scenario, what's the best way to get the IList built in the first post to be used in the second post?
The only way I can think of is using some sort of temporary table to store the list of jobs after the first post and then read from this in the second when updating the invoice table. Is this an acceptable method to achieve what I want? Or is there a better way that my lack of experience is missing? xD
What bugs me about that method above is that if the user leaves the page before posting the second time, the temporary table will then have a list of rogue jobs which could be called up unexpectedly the next time.
Hope I've explained this well enough. Thanks in advance.
The temporary table that you can use (which is built in MVC) is the TempData dictionary. It's persisted inside the Session, and the values get deleted when you use them.
BTW, have you thought of using Ajax instead of posting and refershing? This means that you always have the data with you, as you're on the same page. You don't have to carry state around.
UPDATE:
Errr wait, when you say that the list is NULL are you talking about a List recieved in your Action as a parameter? If you are, this article shows how to databind a collection.
UPDATE 2:
I have had second thoughts about using this method (getting data from the client), as it could lead to some security issues.
If you don't want to query the DB again, TempData/Session is a possible solution.
Since the list of jobs is not modified by the user on the second page, why don't you just grab it again in the controller action that handles your second submit?

Resources