I'm using ASP.NET MVC to create a web application and have stumbled upon a situation where I'm not sure what the best solution would be.
I have a users page where I am simply loading a list of users and their roles into a table. The roles are checkboxes, for example Manager and Administrator are two separate roles that are expressed as checkboxes on that row for the user.
In the far right column is an Actions field with 3 buttons: Save, Change Password and Delete.
Change Password works by opening a dialog box and hitting an action on the Controller called ChangePassword, this is a Post request as the form is in a different area and some values are set to hidden fields using JavaScript.
Delete works by calling an action called Delete which is a Get request where in the view the action parameters are explicitly set by using the values from the Model. Since these values aren't going to change I can safely do something like this:
#Url.Action("Delete", new { loginName = Model.Users[i].LoginName, username = Model.Users[i].Username })
However, the Save action is different because the save action is meant to be used to update the user roles, which the user can change by selecting different checkboxes. My initial plan was to make the Save action a Get request and have the values passed in similar to how I do this with Delete but I would need to set some sort of hidden field using JavaScript so that I know which fields are updated.
An alternative solution would be to have every table row a form and make Save a Post action and have the values from the checkboxes bound to the model on the action. I'm not sure whether this would be advised because this could potentially mean 50+ forms on the page depending on how many users I have.
I'd appreciate some advice on this issue.
Thanks
A GET request should never change the state of your application, i.e. it shouldn't delete or modify users.
I'd use the ASP.Net Membership Provider and call its respective methods in the Controller Actions.
Related
I have a page with a form that accepts a list of account numbers into a text box, a bulk search essentially.
This does posts to the server, does a validation exercise and then if sucessful redirects to a display page.
Currently the list is added as a GET variable in the URL to the display page. This is limiting in that it means users can mess with it and larger data sets may be a problem. It also allows for a bypass of the validation but this is accounted for.
I see 2 general solutions which are basically variations of 1 theme:
Save the list to a DB and pass a key to load this to the diplay page.
Save to MemoryCache and again pass the key to the display page.
Based on these options it seems that 1. is better if I need multiple IIS node but needs manual cache cleanup where 2. will clean it's self up but may be a problem if I need to scale. This will be an intranet applcation so scale will probably not be required.
Is there a "industry standard" approach to this class of problem. I'm coming from the winforms world where keeping track of state wasn't an issue.
I don't think you really have to redirect to the display page at all. From the controller that gets the user input and prints the result just return the View that should render the results like:
public class SearchController : Controller
{
public ActionResult SearchForAccounts(string[] accounts)
{
var searchResults = db.Search(accounts);
return View('ResultsView', searchResults);
}
}
If you really really need to redirect, I guess you chould save the results into the application Cache and later if you need to scale you could use a Redis Cache provider for example, but again you should be able to show the required view.
Whether it's Webforms or MVC, I recommend not getting into the pattern of separating validation/processing and results into separate pages.
I'm guessing that if the data is invalid you want to put it back on the page so the user can edit it. (That's a guess inferred from what you're asking.)
You can post the data, and then if the data is valid then the "result" page shows the results. If the data isn't valid then the page can re-render the input form, populate it with the original inputs, and display a validation error. That way the user can modify their original input and try again. (Just be sure to escape/unescape if you're taking user input and reflecting it back onto the page.) That's easier if the form is a partial view (MVC) or a user control (Webforms.)
I'm making my first asp.net mvc application Forum system. I want before every thread to show picture that shows is there new post or not. Like other forums, if there is something new from last login to show one picture and if there is nothing new show other picture. I am using asp.net identity 2.0.
I am thinking to make partial view and to invoke it where I need it. But how to show picture, depending on every user, I was thinking when user log in to be invoked method that checks every thread if there is something new after last login. Where to put this logic in the mvc project, or in the db project and to store for every user last login date, and to call this method. What is the right way?
I suggest you do this in javascript as you will want the page response to be the same for all users so you can cache it etc
on each thread in your forum add a property of last updated
<div data-lastupdate="put the date there">
in the javascript set a variable for the date of the previous last login for the user
userlastlogin = date
then using jQuery (or whatever) set the picture on all forum divs where the lastupdate is greater than the last login date
I am working in a project that have a Person model. I display the Persons in an Index action with a table, showing Checkboxes allowing to select multiple people.
The user is supposed to be able to do different things to the selected people, like:
Approving them for access.
Sending an email message.
The action of approving them for access is just making a database change. The action of "Sending an email" should redirect to another page that would request the details of the email so it can be send.
So far we have a table inside a Form that have the people. That form is posting to one action and I am able to retrieve the selected IDs. So far so good.
My issue is that I would like the form to post to different routes dynamically (if the user clicks on the action to "approve" the user to go to one place, if the user clicks on the actions to "send email" to go to another place).
I haven't been able to find how to dynamically modify the form action to post to a different Url on runtime. Is there any way to do that? (or maybe I am doing all this wrong, and I should, somehow, collect the IDs with jQuery and post to the Urls that I want).
What you need to do is to change (on the client, using javascript) "action" attribute of the form element:
var url = ...
$("form").attr("action", url);
I'm new to ASP.NET. I'm designing a user interface in Asp.NET and C# where the user can login and then launch an application. When using this application the user has to fill out a form that is 10 pages long.
So, I have used navigation menu and designed the interface in such a way where every page is different menu item and it is a static menu. The user fills out the details on the first page of the form and saves it and the data gets saved in the database.
The problem is he moves to the other page by clicking the menu tab; when he comes back to the first page by using the menu tab for that page all the filled in data is gone and he sees a blank page. I know that is how it works but I want it in such a way that in one sitting when he is filling out the data on the second page (after filling the data on first page) on reverting back to the first page he should be able to see the data that he had filled out.
What concept can I use? I'm not sure view state will be helpful in this scenario.
You should look into using the Session State variable for storing his information over the entire session. If the user is logged in you should think about storing his information that he enters in a database and having a Boolean state of "ApplicationFinished" to check if he has finished it or not. Otherwise I would have a call on each page to retrieve information from the database that has already been added, so that he can fill out information at different sittings or all at once.
http://msdn.microsoft.com/en-us/library/ms178581.aspx
Session State may be too long term for you, and if that is the case do some research on ViewState. There are a lot of different ways to tackle a problem like this. It all depends on which technology will fit your needs the best.
http://msdn.microsoft.com/en-us/library/ms972976.aspx
Also, if you're using a tab system think about using the AJAX tabs so that the data will remain on the forms even while tabbing through the different tabs.
http://www.dynamicdrive.com/dynamicindex17/ajaxtabscontent/
Well, if you are write the data on database, i guess the best (fast) workaround is to add a column named "completed" to the table the hold this informations. If the flag "completed" is not setted to 1, you load the database information and fills the page controls.
When you create a new record in the database, get the ID of the record and set it on Session. If the user gets back to the first page (previous page), you can recover the information ID and load the data.
As long as you are learning new things... add jquery to the list and leverage the JQuery Wizard Plug In. It will allow you to integrate your "10 page form" into a single unit, which can then be sub divided, routed and managed more easily. You can leverage AJAX to save each step, while offering built in navigation and validation methods.
I would suggest that you switch to using client-side javascript to control your tabs. That way your form data stays in the fields when you switch back and forth between tabs. You can use javascript buttons to guide the user from tab to tab.
I've done this using JQuery. I actually had 150 fields that needed to be captured (they were all required). I group like data on different tabs and then had buttons ('< Previous', 'Next >') which would activate different tabs.
When they are done, then display the 'Save' button.
This not be what you are looking for, but if your problem is that you want all of the input of a previously filled page to show up when a user navigates back to it, and you have already saved all that information, then you can try something like this:
HTML
<input type="text" id="yourID" name = "yourName" value = "<%=data%>"/>
Then all you need to do is set data to public in the code behind. Then to get the value for data just make a call to your database.
Make sure that you make data empty on the init call public string data = ""; or whatever type it is. This way if there is no info, then it will be blank, and if there is saved info, then it will be filled in.
You can also attempt to pass all the data through params in the url like so:
C#
Response.Redirect("webpage.aspx?data=" + data + "&data1=" + data1);
Or though javascript:
window.location = ("webpage.aspx?data=" + data + "&data1=" + data1);
To get the request do this:
if (Request.Params.AllKeys.Contains("data"))
{
data = Request.Params["data"];
}
This way is less ideal though if there is a lot of data being passed.
This may be a basic question... However I've just been picking a solution without giving much though to it...
Consider a page with a grid of forms: /FormList.aspx
where choosing to edit a form redirects the user to a page like: /FormEdit.aspx?Id=2
I usually am okay with passing the values in the query string, because I check in the code-behind of FormEdit that the Id is valid. Which is the best way to pass the value, though: session or query string? Or other?
While the user is editing the form... I usually save the Id temporarily in session (to avoid getting it from the url again). During the user's form edition, what is the best way to store the value? In the session or in a hidden field ? Or other? (When I want to store a temporary DataTable, I believe I can only use the session, but when it's an integer value...)
Thanks in advance for your suggestions :)
I would suggest not to use Session for something that can easily and quickly be stored and checked in a query string or hidden form field; the information you seem to be talking about here is perfect for the query string.
Note that Session could introduce bugs when someone attempts to edit multiple forms at once in different tabs. When they save one, the Session value taken would be from the last one they loaded up to save... likely not what you will want, and it would likely be difficult to figure this out.
What you should do is persist the formID in the query string/form fields, and just double-check it for sanity when they submit the save; Make sure it's an ID that exists and that they are allowed to edit, for example.
Normally QueryString is a good choice if you are having very small data to trasfer between your pages.
2- Session would be a great when you want to store user specific data.
in you case , best would be the querystring as you are sending very small data (ID ) to the next page.
A few things to consider:
If manipulation of the value is a security risk you need to either save it on the server side, or secure the value client side(Which isn't easy to get correct). Or even better: recalulate them.
Saving in the session can easily create problems if the user has the website open in several tabs at the same time. It can also break the back button.
For example if you safe the ID of the item the user is currently editing in the session, and the user edits two entries at the same time the content of the one he started editing first might be written into the entry he started editing later.
My suggestion is to keep the value in a session variable, but when you run the page_load of FormEdit.aspx for first time, save the value in the ViewState of the page, and clear the session var.
Something like that (in page_load of FormEdit.aspx):
if (!IsPostBack)
{
ViewState["MyVar"] = Session["MyVar"];
Session.Remove("MyVar");
}
The problem with ASP.NET and query strings is that they persist on postbacks. That is, the form action for any page defaults to the url including the query string that was used to load it.
If the ID in question is just used to choose a particular form (and is not related to user data) this is not a big deal, in fact it's probably what you want.
On the other hand, if it identifies a record, you may not want this. Assuming you code things properly, this should not present a security risk, but it can give the user the impression that there is one by exposing the internal ID of a record in the query string. It also just looks unfortunate.
There are ways to work around this, and I think in 3.5 you can programatically change the form action. (It used to be you had to use javascript to do that - even though the form action was exposed it could not be changed).
The best way to deal with this is avoid query strings for any data record identifiers. Use POSTs to load data records instead, e.g. instead of using an asp:HyperLink control, use an asp:LinkButton control.
Of course, since POSTS load the same page they are sourced from, this requires that your forms be on the same page as your list. So, instead of having two separate pages, FormList.aspx and FormEdit.aspx, just put the code on the same page so you can post back directly. Presumably each of your forms is in a UserControl anyway. So your main page just has the job of choosing which usercontrol to show, everything else is delegated to the user controls, and all the parameter-passing can be done through posts inside your main page. This is a better architecture and keeps everything nice and clean.