internal app needs to query a database on a server in dmz - asp.net

I'm developing an app using asp and vb.net. Hitting a db that is sql2008 r2. There's an internal app which sends an email to a customer. the email contains a link which the customer clicks on, and then the page load of that page updates a database sitting on our dmz. I'm trying to write a service then which will query this database at various times, and then, based on that result, fire off an email to an internal group. Originally this was set up to fire the email from the box on the dmz, however our NA doesn't like having port 25 open like that, so now I have to rebuild the app internally to query that database, so that the inbound email can be generated on an internal box.
SO... my problem is making the connection in Visual Studio (2012). When you configure the sql data source to a box inside the network, all you need is the name of the server, and you'll get the drop down populated with the databases. At first VS wouldn't see the server at all. We turned on "named pipes" on the server, and then I entered the server name as ip,80 (this is the only port the NA will allow open) and now it will see it, however, before the dropdown gets populated, I get an error saying "A connection was successfully established with the server, but then an error... an existing connection was forcibly closed by the remote host." I know sql normally runs on port, what, 1443? something like that? but if I do that, it goes back to not being seen.
Is there a way to configure the sql data source to see this server? I've researched for a couple of days, but generally the topics have been working the other direction, or related to sporadic issues, which this isn't. Our NA isn't much of a programmer, so he doesn't know much about my end, only that he seems sure that using named pipes is the way I need to get in... however, beyond enabling them on the server, I don't know much about them, or if VS can even use them...
thanks in advance.
(I've been coming to this site for a long time now for answers; this is the first time I've ever had post a question)

Wow, a MS SQL Server in your DMZ???
Short answer is to tell your NA he doesn't need to open port 25 for you to SEND an email, unless there is some part of the story I am missing.
The better answer, get that server out of the DMZ and create a web service. They are easy and can be made very secure.

Related

Wrong dependency to IIS restart for getting changed data in SQL Server

I am working on an ASP.NET webforms application with Entity Framework. Also for some reports it uses a dll and in that we have explicit query to get the records from SQL Server (such as ADO).
The problem is that when I change a column such as ParentID in SQL Server, I must to reset the website in IIS to see it and this solves the problem. This dependency is not logical and I want to know why this happens? Is there any relation to caching because of calling method in the dll?
How can I solve this problem?
When you run a query against SQL server (or any database, really), the result that you see is not the data "in the database", so to speak. The query returns a copy of that data that belongs only to you. The copy of the data gets sent over the network, to the client - in your case, an ASP.NET web application - and the application does whatever it needs to do, such as show it to a user.
Once the query which retrieved the data is complete, there is no longer any link between the data in the client, and the data in the database. There is no continuous, "live" connection between the two, even if your actual database connection is still open. The database connection is merely a way to send queries to the server, and for it to send copies of the data back.
It's like taking a copy of a file from a different machine. If you copy a file from my machine, and then I update my copy, your copy doesn't instantly get updated.
If you want data in some user interface to stay perfectly up to date with the data that actually exists in the database, you have a difficult problem to solve. There is no "easy" way to do this. Or perhaps more accurately, there is no simple or efficient way to do this.
This might seem odd to you. You're thinking "well, why not? Why doesn't it just show me the values as they actually exist?". The reason is that these systems need to be able to support many users - often thousands at once - who are all both reading the database and writing to it. Imagine someone was in the middle of updating data in the database, but then they rollback their transaction. Should you see the data as it was being modified, but not committed? What if two users are trying to update "the same" data at once? All sorts of concurrency questions come into play, which basically boils down to questions about locking.
What you are encountering here is a basic principle of multi-threaded environments, which translates to systems with multiple clients: Data can't be accessed directly by multiple people at the same time. Instead, you give each person their own immutable copy.
In a web application things are even more disconnected. When the browser requests the web page, the server side of the web application gets a copy of the data from the database, and then transmits that to the browser. Once the page is loaded there is no longer any link between the web server and the database server, or any link between the web server and the web browser at the client, and certainly no link between the web browser and the database.
Ultimately, this is one of the "hard problems" in computer science. You want to know how to tell the client to invalidate their "cache", and refresh their local data. There are a few mechanisms provided by .NET to do this with SQL Server, but they are quite technical. One of them is query notifications

Send Newsletter in asp.net to around 10000 emails

i have to write application for sending newsletter.
what is the best way to send newsletter thoundands of users?
My requirement is
Each mail is seprately as To :
Every mail has unique Unsubscribe link
Is is good to use SMTP mail class of .net?
I look aound may questions in so but can't decide which approcah i should go?
There are many suggestions
Multi threaded Windows service
Use Mail Server
Add thread.sleep(2000) between each send.
can anyone suggest good way to imepement this?
I would not recommend asp.net webpage to send, even if you do start it in a separate background thread. I would think you run the risk of the server recycling your process in the middle of the send, which would mess it up. You really need to write some kind of separate service or application to send your emails.
The simplest option would be to just create a quick and dirty console or windows form application.
Also logging is critical just like the other poster said. If it fails you want to know exactly what got sent out and where it stopped so that when you restart it you don't mail all the people who it did work for again. You want to be able to input the starting point for the send, so if you need to restart at number email #5000 you can.
The classes in System.Net.Mail namespace will work just fine for sending your mail.
One of the biggest problems will be finding a email host that will let you send so many emails. Most email hosts have throttling and sometime it changes depending upon server conditions so if the server is being heavily used then the email limits will be more restrictive, and you may only get to set 500 emails per hour.
We have a newsletter that goes out to around 20000 people as separate emails and we had to play around with the delay between emails until we found one that would work for our email host. We ended up with 1.2 sec between emails, so that might be a good starting point.
I think there are email hosts specialize in bulk mailings though so if you get one of those it might not be a problem.
Also if you host your own email this may not be a problem. And if you do host your own mail you will have the option of dropping the mail in the pickup directory and you could just dump it all in there as fast as you want, and let the email service pick it up at it's own pace.
EDIT: Here is the settings to add to the config file for setting the pickup directory
<system.net>
<mailSettings>
<smtp from="support#test.com" deliveryMethod="SpecifiedPickupDirectory" >
<specifiedPickupDirectory pickupDirectoryLocation="Z:\Path\To\Pickup"/>
</smtp>
</mailSettings>
</system.net>
Definitely do not do this in ASP.NET. This is one of the biggest mistakes that new web developers make.
This needs to be a windows app or service that can handle this much volume.
I've written pages that send emails, but not nearly the volume yours will. Nonetheless, I would recommend the following based on code I have implemented in the past:
Use the web application to write out the email and all the recipient addresses to database table(s).
Have a process that is outside of ASP.NET actually send the emails. This could be a vbs file that is set up as a scheduled task, or (preferably) a windows service. The process would take the text of the email, append the unsubscribe link, and once sent successfully flag the database record as sent. That way, if the send fails, it can try again later (the send process loops over all the records flagged as unsent).
If you need a log of what was sent and when, you just need to keep the sent records in the database tables. Otherwise, just delete the records once sent successfully.
IMHO sending emails within the ASP.NET worker process is a bad idea because you don't know how long it will take and if the send fails there's little opportunity to retry before the page times out.
Create a webpage to "Design" the newsletter in. When they hit Send, queue the newsletter up somewhere (database) and use another program (windows service, etc) to send the queued letter. This will be many times more effecient and potentially fault tolerant if designed properly.
I have written a Newsletter module (as part of a bigger system) in ASPNET MVC 2, Entity Framework and using the System.Net.Mail namespace. It is kicked off in view and actually just runs in a controller with a supporting method to do the send. As each email is sent I track whether there is a hard bouce (an exception is thrown) and I update that database record stating a fail with the exception, otherwise I update the record stating success. We also do personalisation so we have 'tags' that get replaced by an extra field in the database (stored as XML for flexibility). This helps handle an unsubscribe function.
My code is quite simple (please don't flame me for using exception handling as business logic ;) and it works like a charm.
This is all done on a VPS at http://maximumasp.com which also hosts 4 sites with pretty decent traffic. We use their SMTP servers. We notified them that we needed this service and have had no problems relationship-wise.
We had 2GB of RAM on the machine running Windows 2008 and it was doing 6 emails/sec. We bumped it up to 3GB as the web sites needed it and now the mailout is doing about 20emails/sec. Our mailouts range from 2,000 to 100,000 email addresses.
In short, ASP.NET can be used to handle a mailout, and if you add in some logic to handle record updating the worry of losing your way mid-send is mitigated. Yes there are probably slicker ways to do this. We are looking in to MQMS and threading, and separating that out to windows service to make it more stable and scalable as we put more clients and larger lists on, but for now it works just fine with reasonable reporting and error handling.

Setting up a backup DB server in ASP.NET web.config file

I currently have an asp.net website hosted on two web servers that sit behind a Cisco load balancer. The two web servers reference a single MSSQL database server.
Since this database server is a single point of failure, I'm adding an additional MSSQL server for backup. I would like to setup my web.config files to write everything to both MSSQL servers, but only read from the "primary" database server unless it is unreachable for some reason, at which point the backup MSSQL server would be used.
Is this possible via a web.config file setting, or must this be done in code? Thanks in advance for any help.
New Information:
I just wanted to add further information on this topic after researching it for the past several days - Microsoft TechNet has a good article title "Implementing Application Failover with Database Mirroring" (http://www.microsoft.com/technet/prodtechnol/sql/bestpractice/implappfailover.mspx#EMD).
This specifically covers the database mirroring feature in Microsoft SQL Server 2005 and the new new "Failover Partner" connection string keyword that allows you to specify two server/db instances in a single connection string.
The article is well worth a read if your interested in implementing this type of feature.
What you want is called "failover", where if one database fails your queries are automatically redirected to the other. This is acheived at the database level, not the application. There are a lot of walkthroughs etc for setting up failover clusters: here's one for SQL 2000, and another for SQL 2005. Basically, once you set it up, the primary database communicates all activity to the secondary one. If the primary fails, the secondary is (almost) up to date and takes over.
The servers form a cluster, and look like a single unit - similar to the way your load-balanced web servers look to the outside world. The backup monitors the primary, and if the primary stops responding, the backup takes over receiving queries. If you're Googling, try also looking adding the keywords "database mirroring" and "quorum".
Its a bit more complex than that. Does your webpage write to the databases? Or just read?
If they write, then you'll have to worry about keeping the 2 databases synchronized, probably using mirroring or log shipping.
But what you are (in essense) talking about doing is setting up a SQL cluster.
I've written a blog entry that shows how to setup MSSQL Database mirroring as well as how to actually utilize it from a managed code perspective:
http://www.improve.dk/blog/2008/03/23/sql-server-mirroring-a-practical-approach
Nice answer from "Rick" but I just wanted to add my 2 cents of information. Normally for a setup with failover without a lot of expensive equipment, I would set it up like that:
You can have your 2 SQL Server box waiting for request and have a third box low-end system with SQL Server 2005 Express as a "health monitoring". What that saves you is 10K$ for the box and one SQL Server licence. SQL Server Express (as in Free) can do the health monitoring between the 2 databases servers without any issues.
That is my setup :)

Anybody know why SQL Server 2005 throws "'SQLOLEDB' failed with no error message available, result code: E_FAIL(0x80004005). "?

We've got a web system running SQL Server 2005 for the back end, and ASP.Net for the front end (using .net 2.0).
Every now and then, the system barfs out the error in the title: 'SQLOLEDB' failed with no error message available, result code: E_FAIL(0x80004005).
The web system runs just fine 24/7, and then every now and then will toss this out on a select or some such. I've tried re-running the exact select that throws the error, but (of course) it works fine when I do it. And, to answer the obvious follow-up question, no we haven't done any code changes or upgrades to speak of lately.
Has anyone ever run into this before? Nosing around on google seems to only turn up situations where Access has some kind of file issue (permissions, missing data file, etc.)
Firstly, it's probably not SQL Server throwing out the error, and if it is, it's probably not while running the SQL statement itself, but if it is, it's almost certainly going to be peculiar to a login that doesn't have permissions, not the SQL command itself.
The 0x80004005 error is a general permissions failure, and it can occur in just about anything, but it's most likely to be in another layer.
I've seen it in authentication when the account the application is running under does not have access to the network to open a connection to the SQL Server. The SQL Server never even sees the request, but the client will say that the server cannot be found.
If it's intermittent, that could point to an intermittent domain controller issue, but that would depend on how your Windows Servers and Active Directory are set up, and how your application is connecting to SQL Server.
To solve this one, your netadmins will need to really know their Windows logging functionality and track it down for you.

What's the ASP.NET Connection String Format for a Linked Server?

I've got a database server that I am unable to connect to using the credentials I've been provided. However, on the staging version of the same server, there's a linked server that points to the production database. Both the staging server and the linked server have the same schema.
I've been reassured that I should expect to be able to connect to the live server before we go live. Unfortunately, I've reached a point in my development where I need more than the token sample records that are currently in the staging database. So, I was hoping to connect to the linked server.
Thus far in my development against this schema has been against the staging server itself, using Subsonic objects. That all works fine.
I can connect via SQL Server Management Studio to that linked server and execute my queries directly. I can also execute 'manual" queries in C# against the linked server by having my connection string hook up to the staging server and running my queries as
SELECT * FROM OpenQuery([LINKEDSERVER],'QUERY')
However, the Subsonic objects are what's enabling me to bring this project in on time and under budget, so I'm not looking to do straight queries in my code.
What I'm looking for is whether there's a way to state the connection string to the linked server. I've looked at lots of forum entries, etc. on the topic and most of the answers seem to completely gloss over the "linked server" portion of the question, focusing on basic connection string syntax.
I don't believe that you can access a linked server directly from an application without the OpenQuery syntax. Depending on the complexity of your schema, it might make sense to write a routine or sproc to populate your staging database with data from your live database.
You might also consider looking at Redgates SQL Data Generator or any other data gen tool. Redgates is pretty easy to use.
One other idea - can you get a backup of the live database that you can install in development to do your testing? If its just data for development and testing that you seek, you probably want to stay away from connecting to your production database at all.
Create testing stored procedures on server B that reference the data on server A via the linked server. e.g. if your regular sproc references a table on Server B say:
databaseA.dbo.tableName
then use the linked servername to reference the same database/table on server A:
linkedServerName.databaseA.dbo.tableName
If server A is identical in its database/table/column names than you will be able to do this by some quick find/replace work.
creating a linked server from .NET doesn't make any sense since a linked server is nothing but a connection from one sqlserver to another server (sql, file, excel, sybase etc etc), in essence it is just a connection string (you can impersonate and do some other stuff when creating a linked server).
One Way is to create two connection strings and access the approperiate database when required.
Second option is create connection for Database A only and create a link server For Databse B in Database.good article, i really like it. I am doing a bit on research about Asp.net connection and i found also macrotesting www.macrotesting.com to be very good source. Thanks for you article.....
Regards...
Meganathan .J

Resources