In ASP.NET, can I store parameterized sql queries in .resx files and not get into trouble when I have several users logged in at the same time?
For example, i'll put my user detail query in a .resx file:
SELECT * FROM User WHERE UserId = #UserId
How will ASP.NET treat it? Like a "Session" (different users have different results) or like a "public static"/"Application" ?
resource files are typically for storing language specific strings, not for storing queries to execute, I guess you could do it, but why? It seems that there is a piece missing from your question, what is driving this requirement on your end?
EDIT: If you only have access to mysql, why not use an ORM tool like subsonic or nhibernate
I'm not intending to comment so much on whether this is a good idea or not, but basically, aren't you just storing strings? When you use a parameterized query, in ADO.NET at least, you will add the parameters before running the query.
#UserID would have to come from your code, which needs to somehow obtain the value from the logged-in user (or however your app works), so it doesn't matter how static or not the strings are.
That said, you should be using stored procedures if possible instead of this.
Related
There is a page in my company that contains only a GridView with some data
Today i saw this text in one of the cells (i changed a little to show to you)
[div style="display:none"]discount online BLABLABLA[a href="http://www.[randonURL].net/page/[randompage].aspx"]click[/a] new prescription coupon[/div]
I searched this text and somehow, someone inserted this in my database
How he made that?...what i can do about it?
It sounds like a classic case of SQL injection. There are a number of things you can do to prevent it. Here are a few. I would suggest reading up on it though.
On your database methods always use parameterized SQL, stored procedures or an ORM. Never use dynamic SQL. In the rare case you have to, there are ways of protecting that too. But that is a fairly long discussion.
Always encode user input. For JavaScript use the encodeURI() method. On the server side use the HtmlDecode() method.
Never show error details in the public domain. This gives hackers clues they can use.
Search is the most used feature on our website and the search query is the most CPU intensive, complex and frequent query that executes on our db, causing heavy CPU usages on the db server. To reduce the load on the db we have been looking at various caching strategies. For now, we intend to use the ASP.NET Cache.
The idea is to have an in-memory db of the most frequently/recently created/accessed objects in the cache and then query the in-memory db using linq to come up with search results. My initial thought was to Cache a List of the Users and then query or modify this List using linq. But given the complexities of multiple threads accessing or trying to modify List I was looking at other options.
Which is when I thought that instead of Caching a List, cache the individual User objects with its Id as the key and try and query the Cache. At http://msdn.microsoft.com/en-us/library/system.web.caching.cache.aspx I see that the Cache has an extension method AsQueryable but I am not sure what does this mean. Cache is a key value pair so with AsQueryable will I able to query the keys and get a set of User Objects or will I able to query the User objects and get my desired result?
Before you start this you really need to have some measurability in place around it -- there is no way to figure out if your changes help or hurt without having some good, solid data to make that judgement on. Performance, especially performance at scale isn't something you can think or guess through. You have to know your way through it.
As for your solution, I think you might well make the problem worse or at least create another problem here. Your database server is theoretically designed to handle arbitrary user queries across vast information sets efficiently. Linq is awesome but it is not really meant to be an ad-hoc search engine -- it doesn't have the sorts of indexing capabilities one really expects from search engines. Just because it can expose things as an IQueryable doesn't mean you should treat it that way. And even if you've got a way to efficently search the cache, you've got another problem to get past -- how do you identify what is most frequently used? And how do you manage the ASP.NET cache to not start ejecting things when it gets low on memory?
You would probably be better served here by:
Starting with some good old fashioned database tuning -- why are your queries so slow and expensive? Are you missing an index somewhere?
Looking at caching the results page output, especially if your search URLs are GET-able as that is pretty easy to manage. This is a great short term solution if the site is melting.
Look at building the search bits properly. Using LIKE %whatever% is not a proper search. Full text indexes in your database is a good start. Something like lucene.net is probably better.
No, cannot use AsQueryable to query User objects and get the desired result I was looking for. So now I will be using a static List for the time being though I know I will have to change sooner rather than later.
I'm currently looking at a terrible legacy ColdFusion app written with very few stored procedures and lots of nasty inline SQL statements (it has a similarly bad database too).
Does anyone know of any app which could be used to search the files of the app picking out any SQL statements and listing the tables/stored procedures which are referenced?
Dreamweaver will allow you to search the code of the entire site. If the site is setup properly including the RDS password and provide a data source it can tell you a lot of information. I've only set it up once so I can't remember exactly what information it gives you, I think maybe just the DB structure. Application window > databases. Even if it isn't set up properly just searching for "cfquery" will quickly find all your queries.
You could also write a CF script using CFDirectory/CFFile to loop the .cfm files and parse everything between cfquery and /cfquery tags.
CFBuilder may have some features like that but I'm not to familiar with it yet.
edit I've heard that CFBuilder can't natively find all your cfqueries that don't have cfqueryparam but you can use CF to extend CFB to do so. I imagine you could find/write something for CFB to help you with your problem.
another edit
I know it isn't indexing the contents of the query, but you can use regex to search using the editor as well. searching for <cfquery.+(select|insert|update|delete) checking the regex box should find the queries that aren't using cfstoredProc (be sure to uncheck the match case option if there is one). I know Dreamweaver and Eclipse can both search for Regex.
HTH
As mentioned above I would try a grep with a regex looking for
"<cfquery*" "</cfquery>" and "<cfstoredproc*" "</cfstoredproc>"
In addition if you have tests that have good code coverage or even just feel like the app is fully exercised in production you could try turning on "Log Database Calls" in Admin - > Datasources or maybe even at the JDBC driver level, just monitor performance to make sure it does not slow the site down unacceptably.
In short: no. You'd have to do alot of tricky parsing to make sure you get all the SQL. And because you can glob SQL together from lots of strings, you'll almost always miss some of it.
The best you're likely to do will be a case insensitive grep for "SELECT|INSERT|UPDATE|DELETE" and then manually pulling out the table names.
Depending on how the code is structured, you might be able to get the table names by regexing the SQL from clause. But that's not foolproof. Alot of people use string concatenation to build SQL statements. This is bad because it can introduce SQL injection attacks, and it also make this particular problem harder.
I'm looking into Asp.net Membership Providership Sql to determine if it fits my needs and have a few basic questions.
It seems to create a lot of tables, many of them I don't think I need. I only need one application and no role management. Can I remove the unused tables or should I just leave them alone?
I need another table where I can associate records with the users created with the Sql membership provider. Is it safe to use the "Membership.GetUser.ProviderUserKey.ToString()" as the primary key for this user. I guess so, but it feels a bit like I'm depending on something that's out of my control since it's Asp.Net that manage it.
Also I'm going to access the database directly, without logging in with a user to get statistics. Is it safe to make Sql queries against the database using the aspnet_Users.UserId (table.field).
I guess what I'm afraid of is that suddenly after an framework update, Asp.Net changes the table layout or something.
Obviously, you can do whatever you want to it once you've generated the tables, but I think you should consider the ramifications of that. The Membership Provider framework works very well and is widely implemented. If you use their implementation, just use it and use the pieces you want and leave the rest alone.
They will be very careful when/if they make changes to it to either tell us of the breaking changes or not make any breaking changes.
The framework allows for you to override many of the provided methods, or you can simply write you own custom provider and base it heavily on the out of the box implementation.
ProviderUserKey is meant to store anything you would need to reference, so you can store a key to a record in your own database to store additional user information. I think it's OK to delete unrelated tables, as long as the features you use don't touch it.
I know it touches aspnet_applications, aspnet_users...
As a last resort, you can always create your own custom membership provider by creating a class that inherits from MembershipProvider.
Is it a bad idea (and if why?) to add a a column to the auto generated asp.net (ASPNETDB.MDF, visual studio 2008, mvc framework) "user roles - database"?
(E.g I want to add the columns RealName and LastName to the aspnet_Users table in the database.)
The reason I want to add a column instead of creating an entire new table is to avoid the doule maintenance issue and unnecessary redundancy
There are two generation schemes that are used (from Pragmatic Programmer):
Those that are used once to generate code
Those that are used all the time to have some code synced
The ones that are used for syncing, the results should not be modified, since they could be overridden at a later date when the generation gets done again.
In the case of your generated asp.net database, there is no reason for you to rerun the generation, so it would be OK to edit it.
The only scenario under which you would rerun the generation of the db is if microsoft releases a new version of the users database and you want to use the new one (in this case you might have to edit some parts of your application, so you could readd those two fields), or if you want to regenerate the database with different options. Both of these happen if you are not happy with your current db.
In my opinion that autogenerated database should be replaced by a normal table in application database or at least there should be an official solution to this problem.
I heard that this is quite good solution: http://www.asp.net/downloads/sandbox/table-profile-provider-samples/
why dont you create a new table with a Foriegn Key restraint? It seems like a bad idea to add a column to the aspnetdb...it will be a nightmare if you ever need to recreate your db...
First, those tables aren't really anything specific to MVC: they're created by/for the default AspNetSqlMembershipProvider. (Also applies to other kinds of ASP.NET applications.)
You could probably add new columns safely, but the membership provider wouldn't "see" them. It does provide its profile mechanism to store extra information (which gets serialized, and stored in the aspnet_Profiles table).
If you need to store lots of additional information about the user, you might also check out this sample membership provider that stores profile information in first-class tables, rather that in profile blobs.