4

I've got this application that works locally and when deployed and using a .mdf SQL Express database file (which I usually use for testing purposes). However, when I change it to work with our SQL Server 2008 the app works but the service doesn't.

For example if in my code behind of a page I have a button that adds data to a table such as this it works fine:

public static string connString = @"Data Source=server1;Initial Catalog=Project;Integrated Security=True";

protected void btnAddProj_Click(object sender, EventArgs e)
{
    using (var sqlc = new SqlConnection(connString))
    {
        sqlc.Open();
        var cmd = sqlc.CreateCommand();
        int intProjectID;

        // Add the project info to the database
        cmd.CommandText = "INSERT INTO tblProject VALUES(@ProjName,@ProjTeam,@ProjStart,@ProjEnd)";
        cmd.Parameters.Add("ProjName", System.Data.SqlDbType.NVarChar).Value = txtProjName.Text;
        cmd.Parameters.Add("ProjTeam", System.Data.SqlDbType.Int).Value = ddlTeamSupported.SelectedValue;
        cmd.Parameters.Add("ProjStart", System.Data.SqlDbType.NVarChar).Value = txtStartDate.Text;
        cmd.Parameters.Add("ProjEnd", System.Data.SqlDbType.NVarChar).Value = txtEndDate.Text;
        cmd.ExecuteNonQuery();
    }       
}

My web.config is setup to use impersonation on that server and all works perfectly well. However, for my service the query doesn't seem to return anything and I get a 400 Bad Request error.

The code for the jquery is:

$.ajax({
    type: "POST",
    async: false,
    url: "Services/ProjectService.svc/test",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function (data) {
        console.log(data);
        }
    });

And for the Service:

[ServiceContract]
public interface IProjectService
{
    [OperationContract]
    [WebInvoke(ResponseFormat = WebMessageFormat.Json)]
    ArrayList test();
}


    public static string connString = @"Data Source=server1;Initial Catalog=Project;Integrated Security=True";

    public ArrayList test()
    {
        var sqlc = new SqlConnection(connString);
        sqlc.Open();
        var cmd = sqlc.CreateCommand();
        cmd.CommandText = "SELECT ProjectID FROM tblProject";
        var reader = cmd.ExecuteReader();

        ArrayList temparray = new ArrayList();


        while (reader.Read())
        {
            temparray.Add(reader[0]);
        }
        sqlc.Close();
        return temparray;
    }

If instead of querying the database I have the service just return static data then it works fine. What could cause my service not to be able to connect to the database when the rest of the code behind for the app works?

LanFeusT
  • 2,392
  • 5
  • 38
  • 53

3 Answers3

2

A database connection from a hosted WCF Service is considered a remote connection so make sure your connection strings specifies the authentication method. So try using Integrated Security=SSPI in your connection string and if that doesn't work make sure that your Application Pool's Identity is set to a domain account that has permissions on the SQL server. :)

RoboKozo
  • 4,981
  • 5
  • 51
  • 79
  • 1
    Sweeeeeeet! That worked yeah, had my DBA check the error logs when trying to connect and I had: `Login failed for user 'DOMAIN\user'. Reason: Attempting to use an NT account name with SQL Server Authentication.` When I changed to SSPI it worked when testing it locally but using the SQL Server, but on the server it still didn't work. DBA mentioned the error was now different: `Login failed for user 'DOMAIN\server1$'. Reason: Token-based server access validation failed with an infrastructure error. Check for previous errors.` I changed the identity and it's all good now! Thanks! – LanFeusT Mar 21 '11 at 17:58
0

You're probably not setting HTTP headers exactly as the service is expecting them, or in the order it's expecting them.

Here's how I'd debug it:

  1. Create a quick test client using SvcUtil.exe.
  2. Install Fiddler, turn it on.
  3. Use the thin client to make a call to the service operation.
  4. Use your web application to make a call to the same service operation
  5. Look at the full HTTP request in Fiddler for each request. Compare them. Figure out where your AJAX call is different, and resolve the differences so it matches what the generated client uses.
Mike Atlas
  • 8,193
  • 4
  • 46
  • 62
0

This could be that you are making a POST but the service is expecting a GET.

Try specifying that the method should be a POST:

[WebInvoke(Method = "POST", UriTemplate = "", ResponseFormat = WebMessageFormat.Json)]

The other this that it could be is that you are using a trusted connection. This means that the security context is the identity of the application pool (if defaults are used). Then you will be making a connection to the database using a local account that does not have access on a database on a different machine.

The strange thing is that based on the error message it should be the first explaination, but based on your description it would be the second.

Shiraz Bhaiji
  • 64,065
  • 34
  • 143
  • 252
  • That didn't work. I tried specifying a username/password as well in my connection string but no changes. I found [something](http://dbaspot.com/forums/sqlserver-server/421305-wcf-service-sql-server-connection-issue.html) about this error unfortunately that didn't help either. My DBA tells me that it should be available on port 1449 but changing my connection string to match that didn't work either. – LanFeusT Mar 19 '11 at 00:56
  • The default port is 1433 so if your database is on a different one it will need to be specified, we normally do this by creating a sql alias. Try logging the error in your code and check the event log. – Shiraz Bhaiji Mar 19 '11 at 15:37