I stucked at a condition , where i need to share values between the pages. I want to share value from Codebehind via little or no javascript. I already have a question here on SO , but using JS. Still did'nt got any result so another approach i am asking.
So I want to know can i pass any .net object in query string. SO that i can unbox it on other end conveniently.
Update
Or is there any JavaScript approach, by passing it to windows modal dialog. or something like that.
What I am doing
What i was doing is that on my parent page load. I am extracting the properties from my class that has values fetched from db. and put it in a Session["mySession"]. Some thing like this.
Session["mySession"] = myClass.myStatus which is List<int>;
Now on one my event that checkbox click event from client side, i am opening a popup. and on its page load, extracting the list and filling the checkbox list on the child page.
Now from here user can modify its selection and close this page. Close is done via a button called save , on which i am iterating through the checked items and again sending it in Session["mySession"].
But the problem is here , when ever i again click on radio button to view the updated values , it displays the previous one. That is , If my total count of list is 3 from the db, and after modification it is 1. After reopening it still displays 3 instead of 1.
Yes, you could but you would have to serialize that value so that it could be encoded as a string. I think a much better approach would be to put the object in session rather than on the URL.
I would so something like this.
var stringNumbers = intNumbers.Select(i => i.ToString()).ToArray();
var qsValue = string.Join(",", stringNumbers);
Request.Redirect("Page.aspx?numbers=" + sqValue);
Keep in mind that if there are too many numbers the query string is not the best option. Also remember that anyone can see the query string so if this data needs to be secure do not use the query string. Keep in mind the suggestions of other posters.
Note
If you are using .NET 4 you can simplify the above code:
var qsValue = string.Join(",", intNumbers);
Make the object serializable and store it in an out-of-process session.
All pages on your web application will then be able to access the object.
you could serialize it and make it printable but you shouldn't
really, you shouldn't
The specification does not dictate a minimum or maximum URL length, but implementation varies by browser and version. For example, Internet Explorer does not support URLs that have more than 2083 characters.[6][7] There is no limit on the number of parameters in a URL; only the raw (as opposed to URL encoded) character length of the URL matters. Web servers may also impose limits on the length of the query string, depending on how the URL and query string is stored. If the URL is too long, the web server fails with the 414 Request-URI Too Long HTTP status code.
I would probably use a cookie to store the object.
Related
I have searched and searched and have not been able to find the answer to this. I'm no stranger to SSRS, .Net (c# and vb.net), SQL, etc...been in it for years. I currently have a multi-select report parameter that is populated by a dataset in my report. There are hundreds of entries, so I built it to be driven by a wildcard character in a preceding parameter. Everything works fine right now. My question is this: is it possible to enter a wildcard value, select one (or more) of the filtered values and then store that/those value(s) on selection so that a user can go back and enter another wildcard value and select from a newly filtered list? (Basically, remember what has been selected in the overall dataset before report execution and create some sort of comma-separated list as the final parameter value to be passed to the report) I realize this may be better served in a web app w/a reportviewer control, but I'm trying to avoid deviating from the native SSRS server if possible. Thanks in advance!
The way I might approach this (not actually done it but the theory sounds ok)
Have 2 parameters for user input, your current one and a hidden one called say #filter (visible) and #filterHistory (this is the hidden one)
Have a textbox (formatted like button) with something like "Refine" as the text. Set the action to call your report again but set the #filterHistory to be something like #filterHistory & ", " & #filter. Basically we keep appending the last user input to the history.
Then your report would filter based on both parameters. You'll have to do some parsing of the delimited parameter now to split it out into the constituent parts but you get the idea.
I've no time to build a test report but hopefully that will point you in the right direction. If it doesn't help or work then comment and I'll see if I can knock up a quick example.
I'm trying to understand the Instagram API.. and all I really want to do is....say i search for #stackoverflow, i'd like to say return 10 results or something... it seems the only one related to what i'm looking for is "/tags/tag-name/media/recent" with a pagination... i messed with pagination but i don't really understand what that meanns?
but then i was reading "On views where pagination is present, we also support the "count" parameter. Simply set this to the number of items you'd like to receive. Note that the default values should be fine for most applications - but if you decide to increase this number there is a maximum value defined on each endpoint."
so there is a way to set a count? i tried to put "1" and "10" as the parameters but i dont think that worked...
i think this is really simple but i just don't understand it fully, thanks for any help
You simply append the count to the query string:
https://api.instagram.com/v1/tags/stackoverflow/media/recent?client_id=CLIENT_ID0&count=10
And to get another set of data there is a next_url property in the pagination object to call (you append the count there as well)
"pagination": {
"next_max_tag_id": "1386358187743",
"deprecation_warning": "next_max_id and min_id are deprecated for this endpoint; use min_tag_id and max_tag_id instead",
"next_max_id": "1386358187743",
"next_min_id": "1390975436314",
"min_tag_id": "1390975436314",
"next_url": "https:\/\/api.instagram.com\/v1\/tags\/stackoverflow\/media\/recent?count=50\u0026client_id=CLIENT_ID\u0026max_tag_id=138833581727630"
}
I have a session variable which is used to store a datatable (which changes depending on how the user wishes to add / remove items (data items in the datatable).
At the last page of the whole web application, I have a submit page to allow the user to submit the selected items in the datatable.
Because I think session variables may expire if the page is left open too long, and to prevent errors arising from expired variables, at the page_load function's !IsPostBack I assigned the session variable to a viewstate variable (so the data will be stored in the page's viewstate and not expire).
if(!IsPostBack){ ViewState["myDataTable"] = Session["myDataTable"]}
1) Is this the standard practice and are there any implications / errors when assigning a session variable to a viewstate?
2) After calling ViewState["myDataTable"] = Session["myDataTable"], is it ok to do Session["myDataTable"] = null ?
It really depends on the kind and size of data you have there.
It is key to remember that you need to treat anything you send to the client as compromised data. Another way to put it, if you'd be ok with an user having available a form that allows them to input every single bit of that data, only then it is ok.
All said, the viewstate is normally signed, but history as proven is a good idea to follow that general security advice.
As for the size, you need to keep an eye on the amount of data being exchanged on each request.
Last about clearing that session value afterwards, asp.net mvc does similar for what it calls TempData. The scenario for its use: pass some data from one page to the next on non post scenarios + and when you don't want it in the query string.
Yes, you can do it. but viewstate tends to slow the page loading due to extra overhead. If your dataset is small it is ok, but if its bigger then look for other alternatives.
How ever I will recommend not to go with this method[security problem,slow etc.], instead device a way so that session dosent expire if any page is open?? how?? use jquery/ajax to maintain a connection with server at regular interval.
If you want to go some further implement sql session. It will be the best.
Hope these info help you.
I'm trying to retrieve an image from a HTTP Handler.
An issue which I'm having is trying to make it so that only the application can access the image, I've tried editing the anonymous IIS authentication to allow the application pool identity but this still lets users through.
Here's an example:
ASPX page makes a call to the handler (picService.ashx?id=1) passing in an ID via query string
HTTP Handler sends back image
The image source is Services/picService.ashx?id=1
This all works fine. Now if a user wanted to go and visit picService.ashx and type in any old ID, it would return the image which correlates to that ID. I'm working with sensitive information so this isn't acceptable.
I've had a look at HTTP Forbidden handlers but I'm not sure whether I'm going down the right route.
I've also tried returning the image in the ASPX page but you can't do this due to the Image control needing a URL.
How can I return an image from a database and have the source of the image be secure?
Should I be doing this a different way? Or am I on the right track (http forbidden)?
A technique I have used in the past is to have the page (step 1) create a GUID, and register a cache item keyed by the GUID that has the actual image URL in the object. The page constructs the url for the handler, using the GUID and passes to the handler
The handler (step 2) then knows to go to cache to get the actual value and return the content.
This way you only expose the temporary "magic" value. Its definitely obfuscation and not a substitute for proper security.
As an example (from memory, syntax may be off a bit)
In the aspx or caller
string keyValue = Guid.NewGuid().ToString();
int yourImageID = 5;
Cache.Add(keyValue, yourImageID) //expire in 5 or 10 seconds
string url = "Handler.ashx?imgID=" + HttpUtility.UrlEncode(keyValue);
Response.Redirect(url, false);
In your handler (I use ashx mostly, choose whatever suits your need)
string key = HttpUtility.UrlDecode(context.Request.QueryString.Get("imgID"));
int yourImageID = (int) context.Cache.Get(key);
//get your image from the db and return the content
Again, just because I used a guid doesn't mean you have to, but if you are trying to obfuscate the IDentity, then choose something that does not correlate to the IDentity.
The way you word your question there is no way to get it 100% secure. So what trade-offs are you willing to allow and what are you not?
What exactly are you trying to prevent? Only one user not seeing another user's image? Or prevent right-click, save image as as well?
One idea that comes to mind is combine the user's ip address with the id of the image, hash that, throw it in a cache (or use a guid as a key to look up those values). Maybe remove it from the cache once that hash is used, therefore only allow the image to be loaded once by one ip per page it is supposed to be on.
You should be able to throw the mapping between a generated ID and real into the session, or HttpRuntime.Cache.Insert(cacheName, cachedValue) Database is probably not the best answer, they are small amounts of data, and you can set the expiration time to a small value, so unless you have millions of users at a time...
Using a Flash control to load the image would be secure in terms of can't right-click save image as. Also probably could encrypt the stream, or split apart the image headers or something if you're worried about someone intercepting the image stream. They could still get a url to the image, but your flash control could use special headers which would be difficult for the average user to ever figure out.
First and foremost you have to know what do you consider as OK to show photo . What is your authentication parameter. Like if user is allow to see the pic when is authenticated , check the same in , ashx page before allowing it to see. Because calling inside the html as src or putting the same in browser does not make any difference for server . So you need to check some validation in case user is not at all supposed to see in any way directly or in directly
Store the URL and parameter in Session state and access the Session in the HttpHandler. To do this you would need to implemement the IRequiresSessionState in your handler:
Problem with HttpHandler and session state
Getting Session State in HttpHandlers (ASHX files)
Consider the following scenario:
http://www.yourdomain.com/Default.aspx?p=2
Now we ofcourse want to check if the querystring parameter p doesnt contain errors.
I now have this setup:
1) Check if p exists
2) Filter out html from p's value
3) htmlencode p's value
4) check if p is integer
5) check if p's integer exists in db
This is how I usual do it, though step 5 is ofcourse a performance hit.
Kind regards,
Mark
My view: Generally a querystring parameter of this kind isn't really "entered" by users but is submitted as a link. So over-complex slow validation isn't really necessary.
So I would just pass this through to the persistence / data layer and handle any errors that come back as a regular 404 Not Found or 500 Internal Server Error depending on the kind of system I'm working with.
If your intent is to use the parameter to retrieve something from the database, why filter out html or encode it? It's not like you're going to store it in the database, or display it on the front end. Just immediately throw it to the DAL if it exists. You're DAL should be smart enough to tell you if it failed to retrieve a record with that ID, or if the ID couldn't be parsed, etc..
If you are going to convert the input to an integer anyway, then steps 2 and 3 are not needed - just use int.TryParse to see what you have. I would encode and test the input for html only if you are expecting a string which you will use in a dynamic sql statement, or will be displaying on your site
What about:
int p = 0;
if(!Int32.TryParse(Request.QueryString["p"], out p))
throw new ArgumentOutOfRangeException("p");
Quite simple. For most data types (integers, decimals, doubles, dates and booleans) there is a very strict format. If the value does not parse under the strict format, it's an error.
Strings sometimes have a strict format, like an email address or a phone number. Those can be validated with a simple regexp. If it conforms, use it, otherwise it's an error.
Most of the time however strings will simply need to be persisted to the DB and later displayed again. In that case no processing is needed, aside from escaping when inserting into DB (unnecessary as well if you used parametrized queries)k, and HTML-encoding when rendering to the display.
This way any and all data is validated, and there is no risk of any injections whatsoever.
The rare exception of a loose format for a string is, well... rare. I can't think of any right now. For that you can afford some more extensive parsing and processing.
Added: Oh, yes, checking whether IDs (or other values) are valid in respect to a DB. You're doing it right, but think if you always need it. Quite often you can put the check into some other query that you have to do anyway. Like when you select data based on the ID, you don't need to explicitly check that it exists - just be ready that your query can return no data.
Sometimes you don't need to use the value at all, then you can simply ignore it.
But, of course, there are other times, like when inserting/updating data, that you indeed need to explicitly check whether the data exists and is valid in the current context.