Exposing server-side state through client-side controls in ASP.net - javascript

Hopefully this isn't a redundant question--I'm not really sure how to word it. Let's say I have a list of items on an ASP.net page. That list is selectable in that whenever the user clicks on one, the page does a postback and the server code stores the index or some unique identifier of the picture in a ViewState property indicating that it is currently selected.
I would like to minimize the load on the server and therefore I would like to store the index or unique identifier representing the image in some way on the client side. The best way I can think to do this is to store said information in a hidden field ), however I had two questions about this before I go crazy:
Is this a security risk in any way, shape or form (i.e., exposing implementation details of the page)?
Is there a better/best way to do this that is more industry-standard? Does ASP.net provide a framework to do this that is cleaner than my idea? Seems like this would be a fairly common requirement to me...
I have been working in ASP.net for about two years now. Please, be kind :-)
Best,
Patrick Kozub

The only security risk would be if some list items must remain non-selectable. It sounds like that is not the case in your situation. The user already knows the information, because he or she already selected the item.
NOTE: If the server ever does anything with that information and pulls it back from the user, then you must validate the index value. Otherwise, the user could change it to an invalid index, such as (-2), and trigger an exception.
You can store the index (or related value) in a global javascript variable. If you're avoiding a trip back to the server, .NET doesn't really have a role to play.

Related

Efficiently validate that data on a page hasn't been changed by someone else since you loaded?

We have a page which contains a lot of user editable data that is populated from various tables in a database. The data is in all different forms, dropdowns, checkboxes, input boxes, text areas, etc...
There have been some conflicts where two users load a record around the same time, one makes changes, and then another makes a set of changes. When they save they are unaware someone else made a change and may have just broken a change they made or overwrote their change.
I am trying to implement a solution to mitigate this problem, such as flashing the user an error when the data was changed by someone else.
I am wondering if there is a best practice way to check for this problem? Some ideas I had are
Submit both 'current' data present in the field, and the 'original' data. Then check which are changed and compare them in the database to see if the defaults differ from what is currently saved. This would work, but seems to be the least performance friendly.
Use jquery/javascript to detect when a field has been edited, and if it has changed from defaultValue then set a hidden field which will be submitted to indicate it's original value. Then it would do similar to what the previous idea did.
Set a hidden field with a timestamp of when the user loaded their page. When they submit, use that timestamp and check our history table to see if any data on the page was changed since that timestamp. This seems to be the most efficient idea and likely easiest to implement.
Are there any better options or a best practice way to do this? I feel like I am reinventing the wheel for a common problem.
You are solving a common problem. But it's common because it needs repeatedly solved so frequently. "Optimistic Record Locking" is your path forward. It looks like yii (which I am not familiar with) has capabilities to incorporate handling this. I found this link.
Whether the yii infrastructure does this for you, or you have to build it yourself, what you want to do (to support Optimistic Record Locking) is the following:
Make and Keep an unchanged copy of your data when you retrieve it to the Client.
The Client must submit the changes together with the unchanged copy of the data back to the server.
The Server's 'update' routine compares the unchanged
copy to the current record(s). If something has been changed, then it must
return an error msg and the 'new' current record.
If nothing was changed, then the Server does the update.
The alternative is Pessimistic Record Locking, which you can check out. I avoid it due to other issues it has, but there are scenarios where it is more appropriate.

Django - Dynamic number of ModelForms based on dropdown value

I have a form that registers teams of people. Based on a dropdown to select the number of members in the team, the form should show that many model forms, one for each member.
I am not particularly sure what the correct design patter for this is. Here are the solutions that I have come up with:
Use JS to generate the HTML for each member form and then use the Django ModelForm backend to parse each form. However, in this case I cannot use the inbuilt rendering functions of Django and validation notification becomes bothersome.
Send a GET request whenever the user changes the dropdown value, and the GET request specifies the number of members you want to add. But here it would result in any previously entered data being cleared.
Send a POST request via JS whenever the dropdown is updated, and then re-render the form with the appropriate values picked up from the POST request. I am not sure if this is the right way to do this and seems to be easy to get wrong.
Can you please advise on what is the best solution for this scenario?
I am pretty sure this has already been answered somewhere, but I can't seem to find it anywhere. If you have the link to the answer, please go ahead and mark this question as a duplicate.

Displaying a JS var across different pages

This is a kind of difficult question because I'm not sure how to word it. I'm making a shopping cart website using HTML5 and JS and I've got most of it down, but need help with one important aspect.
At the moment my "Buy Now" buttons are in tags that link to 1 page where the user can enter his info and make the purchase, this page is called "checkout". I want this "checkout" page to display the price of the item he wishes to purchase.
For ex) The user clicks on an book worth $10.00 and clicks the buy now button. This button will send him to the confirmation page where it will show a fill form, but the page does not show the price of the item he is purchasing.
This is where my problem lies. I can't think of any solution for this besides making a different page for each product (I only have 9 products).
Also, if it isn't blatantly obvious, I'm still a beginner with JS. Any help would be appreciated in helping me figure out how to display the price on the "checkout" page of each specific item without creating 9 separate pages. Thank You.
If I understand correctly, you are asking how to store a variable in Javascript that can be retrieved by multiple pages.
The canonical way to do this is to use cookies. The native cookie library is rather messy, so I recommend using a cookie library, like this.
However, since your question is tagged html5, you might be open to the sessionStorage HTML5 solution for this, which is much simpler than cookies.
sessionStorage.setItem("price", 100);
var price = sessionStorage.getItem("price");
The best way is to use some serverside solution. The client sends his form to your server, where the form gets evaluated and an according html-page is rendered.
The only other way is either using cookies or local Storage - but that's rather ugly.
You definitely should read some tutorials about php and mysql, but I'll give you rough overview on how to achieve this.
You provide a form on your page like this:
<form method="post" action="your-serverside-phpscript-that-processes-your-form.php>
How many Ipads you wanna buy:<input type="number" name="ipads">
<button type="submit">
</form>
now on serverside your php-script can evaluate the form.
all formfields are stored in a $_POST array. ( $_POST["ipads"] ) gets the value the user entered in the form. You don't need to store these values in the database yet.
You evaluate the formvalues and create the checkout-page with the according data (total price). Now the user submits the checkout-form, which you again process and store in the database.
I won't write down (sry, too tired) how this serverside part works, there are tons of tuts out there, just search google for php+mysql.
Since you're wanting to persist this data all on the client-end, I would encourage you to check out Amplify.Store. In full disclosure, I am currently employed by the company behind it - but it's great, and free.
Saving data is easy:
amplify.store( 'cart', { name: 'Book Title', price: 10.99 } );
To access this a little later, you can simply call:
amplify.store( 'cart' );
This will return your object from which you can get all of the products currently loaded. Amplify will evaluate your system and determine which storage method is best, and use it. This removes all of the guess-work form your plate, and let's you just do what it is you're wanting to do.
Please understand that while it is convenient to persist data client-side, it is by no means secure. When dealing with transactions and issues of a financial nature, you should always keep figures out of the hands of the consumer.
Generally data like this is stored server-side, within a session, a database, or a combination of both. However, if you understand the risks, and your model permits this type of persistence, then by all means feel free to use this as a solution.

Best practice for handling errors in forms submitted via ajax?

I'm wondering what is considered best practice for dealing with forms submitted via ajax. Specifically, I'm wondering what is the best way to handle a form which contains errors.
I see two possible options upon submitting a form with errors:
A. The server returns a JSON document of name value pairs of fields names / error messages. This would then need to be processed client-side and the form would need to be altered by prefixing each field with it's error message and changing the form's styling (adding an error class to the fields for example).
OR
B. The server simply returns a new HTML fragment containing the form with error messages and styles pre-applied. No need to process anything client-side except swap-out the form.
To me option B seems like the easier/quicker option but I can't help but feel that it isn't 'best practice'. Is there pros/cons for either method?
Separation of logic is a huge one here I reckon.
As a project grows, you generally have a front-end team and a back-end team. Imagine the website gets a huge makeover but the logic stays the same. Option B is harder to change the style when the layout is enforced server side.
The application logic (which is this case is server side validation) should be separate from the presentation layer (which is this case is the html/css rendered by the browser).
But at the end of the day, we get paid to produce results so if your not trying to win an academy award for best quality code, and you got bills to pay, just get it done the quickest way.
I'd go with the first option.
The second option just increases the load on the server ... which you always want to avoid. Plus, I feel that if the styling was done on the server-end, the your website isn't exactly modular ... all styling should be done on the front end only.
This is sort of an opinion question but there are a few objective things to say about the topic. Your first option, the pure JSON choice is best used for apps that focus on speed an keeping HTTP requests as small as possible.
The other option, to process your form server-side then return the new form through AJAX doesn't seem to have too many advantages to me. If you're going that route then why bother with AJAX at all? Why not just do a regular form post to the server?
I usually prefer a front end validation and server-side verification. This way you can avoid a JSON call at all if things aren't valid but just in case someone sneaks something in there the server-side code will verify.
I would establish a JSON scheme for validation on the front end. Just basic stuff like what you're checking for on each field, which fields are optional, etc... That gets baked into every page with a form on it. Then let your front end devs pre-validate to avoid unnecessary calls in whatever way makes the most sense to them.
Pre-built errors isn't against any best practice I'm aware of and it's not a terrible way to go (people tend to throw the UI manual of style out the window when it comes to forms anyway), but sometimes you'll want to give more specifics or different errors for different problems.
Always aim for having your cake and eating it too, IMO.

Equivalent of SPContet.Current.ListItem in Client Object Model (ECMAScript)

I'm integrating an external application to SharePoint 2010 by developing custom ribbon tabs, groups, controls and commands that are made available to editors of a SharePoint 2010 site. The ribbon commands use the dialog framework to open dialogs with custom application pages.
In order to pass a number of query string parameters to the custom applications pages, I'm therefore looking for the equivalent of SPContext.Current.ListItem in the Client Object Model (ECMAScript).
Regarding available tokens (i.e. {ListItemId} or {SelectedItemId}) that can be used in the declarative XML, I already emitting all tokens, but unfortunately the desired tokens are not either not parsed or simply null, while in the context of a Publishing Page (i.e. http://domain/pages/page.aspx). Thus, none of the tokes that do render, are of use to establishing the context of the calling SPListItem in the application page.
Looking at the SP.ClientContext.get_current() provides a lot of information about the current SPSite, SPWeb etc. but nothing about the current SPListItem I'm currently positioned at (again, having the page rendered in the context of a Publishing Page).
What I've come up with so far is the idea of passing in the url of the current page (i.e. document.location.href) and parse that in the application page - however, it feels like I'm going in the wrong direction, and SharePoint surely should be able to provide this information.
I'm not sure this is a great answer, or even fully on-topic, but is basically something I originally intended to blog about - anyway:
It is indeed a pain that the Client OM does not seem to provide a method/property with details of the current SPListItem. However, I'd venture to say that this is a simple concept, but actually has quite wide-ranging implications in SharePoint which aren't apparent until you stop to think about it.
Consider:
Although a redirect exists, a discussion post can be surfaced on 2 or 3 different URLs (e.g. Threaded.aspx/Flat.aspx)
Similarly, a blog post can exist on a couple (Post.aspx/EditPost.aspx, maybe one other)
A list item obviously has DispForm.aspx/EditForm.aspx and (sort of) NewForm.aspx
Also for even for items with an associated SPFile (e.g. document, publishing page), consider that these URLs represent the same item:
http://mydomain/sites/someSite/someLib/Forms/DispForm.aspx?ID=x, http://mydomain/sites/someSite/someLib/Filename.aspx
Also, there could be other content types outside of this set which have a similar deal
In our case, we wanted to 'hang' data off internal and external items (e.g. likes, comments). We thought "well everything in SharePoint has a URL, so that could be a sensible way to identify an item". Big mistake, and I'm still kicking myself for falling into it. It's almost like we need some kind of 'normalizeUrl' method in the API if we wanted to use URLs in this way.
Did you ever notice the PageUrlNormalization class in Microsoft.SharePoint.Utilities? Sounds promising doesn't it? Unfortunately that appears to do something which isn't what I describe above - it doesn't work across the variations of content types etc (but does deal with extended web apps, HTTP/HTTPS etc).
To cut a long story short, we decided the best approach was to make the server emit details which allowed us to identify the current SPListItem when passed back to the server (e.g. in an AJAX request). We hide the 'canonical' list item ID in a JavaScript variable or hidden input field (whatever really), and these are evaluated when back at the server to re-obtain the list item. Not as efficient as obtaining everything from context, but for us it's OK because we only need to resolve when the user clicks something, not on every page load. By canonical, I mean:
SiteID|WebID|ListID|ListItemID
IIRC, one of the key objects has a CanonicalId property (or maybe it's internal), which may help you build such a string.
So in terms of using the window.location.href, I'd avoid that if you're in vaguely the same situation as us. Suggest considering an approach similar to the one we used, but do remember that there are some locations (e.g. certain forms) where even on the server SPContext.Current.ListItem is null, despite the fact that SPContext.Current.Web (and possibly SPContext.Current.List) are populated.
In summary - IDs are your friend, URLs are not.

Categories