Maintain SelectList Options over postbacks - asp.net-mvc-3

I was wondering if there is a way to maintain your list of options on a Select List in MVC 3. I am pretty new to MVC but in WebForms you could populate the DropDownList on the first load of the page and then the ViewState would maintain that list for all of the AutoPostBacks. This was nice because often, DropDownLists are populated by query to the database. I know that ViewState does not exist in MVC but is there a better way of repopulating the SelectList without having to hit the database during the request of every post?

You have several options here.
Your selected value will be posted back. With that in mind since you no longer have ViewState you ideally want to
Have your Repository (if you dont have one - create one. You simply ask the repository for the data and it controls the caching or loading) that you ask for the data in the drop down, cache the data and just simply request it again. Rebind your list (use DropDownFor)
Use MVCContrib's Html.Serialize to essentially ViewState it, however the cache is a bit cleaner and doesnt rely on data sent back and forth.
Also remember that after you post your data, if everything is 'good' you want to REDIRECT back to your "GET" action to reload the data and display to the client. This was an issue in web forms that sometime a user saw XYZ after postback but after a refresh saw YXX. Using the PRG pattern in MVC posts-redirects-gets to load up fresh data.
After your post you should generally only redisplay the data if there was a validation error, otherwise redirect to a get method.

Your controller receives the value on postback. You have to place that value back in the model to tell the view what the selected value is.

Related

Writing variables to session from within an Element?

I have an element which is rendered via ajax on my "posts/add" view. The element counts the user's clicks with jQuery and saves it in a variable (let's call it $clickCount).
Now, I would like to pass $clickCount back to the /add view, so I can then save it to the database together with severall other form inputs.
I passed $clickCount to the controller (via Ajax) and tried saving in the session, but it seems like the /add view doesn't see it at all. It's as if the element has a completely different session (which to me makes no sense?). So even though I get the variable passed back to my controller, I can't access it from the posts/add view.
I have spent way too much time on this, I really hope someone can help.
Sounds like it might be because you are making an ajax call to save the session variable, but then you have to remember that you haven't refreshed the page, so the session on the page has not changed, and therefore your new session value isn't available to the view yet.
If you don't want to refresh the page after saving the session value, then you need to return the value back as the response from the ajax request, and add it into your page using JavaScript. You could write it into a hidden form field or something if that is appropriate for you to save it later into the database.
Or, if possible, save the value to the database when you make the ajax request in the first place, and eliminate the whole session thing (if this won't impact the database).

It's possible to pre save the knockoutjs view model to prevent refresh and data lost?

i have a MVC3 project with KnockoutJS and in my view.
The form that the user fills, has information already loaded from the server and the user is filling and selecting from this data so then, the user saves the data selected.
So... sometimes, the user, in the middle of the form, realize that some data is missing and it must cancel the form fill and edit the data that is missing and come back and do it again. So, my question is this... can i persist the view model in some way that the user can edit the missing data in other tab or window in the explorer and then refresh the form and dont lose the data?
I hope the explanation was clear.. my English is a little bit rusty.
Thanks!
Yes, you can. If the data is on the same page, you could save the viewmodel data to another object, possibly using ko.toJSON. Then you can pull it back in later.
If you have to reload the page, you could save the viewmodel or the form's state in storage, using a library like amplify.js. http://amplifyjs.com/api/store/
pseudo code:
amplify.store('myData', myViewModel);

asp.net mvc - Data lost on post back

I have a form that only has a checkbox. If the checkbox is not checked then the page won't be valid and won't submit the data. On the view I have out putted some fields from the model object, just to let the user know what they are deleting. When I click the Submit button and the model state is not valid the page will show the validation error but the data from the model is no longer there!
Does anyone know how I can persist this data without making another call to the database to populate the model object?
Thanks
ASP.Net MVC will not magically persist model info.
You need to either include it in hidden fields in the form (which an attacker can modify), or re-fetch it from the database.
If you don't repopulate the Model from the DB, you have to postback all the data, using hidden fields for example.
Anyway, I don't understand how the model validation could fail, being just a checkbox :/.

How to Handle Mutiple Model Bound Forms

I am buiding a UI screen for editing the details of an Ecommerce Order. The model for my view (OrderModel) has everything I need (in properties that are also ViewModels), but the UI isn't designed to be able to edit all of it at once.
For example, one part of the UI is for customer data..another for order details, and another for tracking information, each having their own "Save" buttons.
I realize that I could use one giant form and use hidden form fields to populate the non-editable fields, making each "Save" button post all the data, but that smells bad.
I'd like to segment the editable chunks into smaller ViewModels that are posted and validated individually while retaining the strong typing but I'm unsure of how to achieve this in MVC3. Will I need partial views that are called from the primary view?
FYI, I'm using ASP.NET MVC 3 with Razor syntax and client side FluentValidation.
Partial Views are a good solution. You can pass different ViewModels to each partial view. But if only sections of the overall view are updated at a time I would not do a post back on the whole page. Instead I would use Ajax calls using JQuery/Javascript to update the individual information back to the controller. I would also look into something like Knockout.js to handle the data binding on the page.

HTTP POST and graceful degradation

I have a web application which among other things contains a table of items created using an Ajax callback. A bunch of form fields at the top of the table allow me to filter the items that will be displayed in the table according to various criteria and show it.
Some parts of the table have lists of items with an [X] marked next to them that I can delete by clicking on those items.
Now, if I were doing this the non-ajax/javascript way, the page would receive a bunch of POSTed data fields and then would render the table accordingly. I can do this but I would also like to Ajaxify the entire setup. My questions are regarding this.
How would I create the [X] button. A simple <a> would "work" but it's a GET modifying state so I don't want to do that. The way I'm doing it now is a tiny form with a hidden parameter than holds the item to be deleted and a styled submit button that's the [x]. If I ajaxify this, I can get the response and do the needful.
How do I keep my backend DRY? I don't want to have two completely different bits of code for the Ajaxified version and the regular ones. What I'm doing right now is having the non-ajax version submit to a URL that changes the state and then redirects to the main page again (similar to a PRG type system). With the Ajax enabled, I simply call the URL and ignore the redirect but use the returned data to adjust the table. Is this the "right way"?
Any other advice on graceful degradation on how to keep my backend DRY?
I would put each row into it's own form (with method='POST'), and include a hidden field to say which item is to be deleted. The [X] would submit the form, and in the form's submit event, if no XmlHttpRequest is present simply submit the form to the server which would delete the item and redirect to the same page again (this is good practise to avoid a reload from resubmitting the delete POST).
If an XmlHttpRequest is present, set it up to POST with the id of the thing to delete and then remove the row if the request succeeded. You could set a flag in the AJAX request so that redirect doesn't happen, just a success (200 OK).

Resources