web service - web client function will not write to db - wcf

I am unable to write any records to my database using a web service. Service is set up OK and can access it via uri and also query my database via the service using a simple page i created.
When it comes to writing to the database, I am not getting any errors, and the instance of my WebClient which is populated with variables to write to the db is holding all the variables OK but when it comes to actually writing to the db (see below code) nothing seems to happen except that the Member ID of the last existing member added to the database is returned.
'assign all abMem fields to values within form to write to database
newMem.Title = ddTitle.SelectedValue
newMem.Initials = txtInitials.Text
newMem.Surname = txtSurname.Text
newMem.Address1 = txtAdd1.Text
newMem.Address2 = txtAdd2.Text
newMem.Address3 = txtAdd3.Text
'etc etc .... additional fields have been removed
Try
cc.Open()
cc.CreateMember(newMem)
returnMem = cc.GetMember(newMem)
MesgBox(returnMem.MemberID & " - Member Created")
cc.Close()
Catch cex As CommunicationException
MesgBox("CommEX - " & cex.Message)
cc.Abort()
Catch tex As TimeoutException
MesgBox("TimeEX - " & tex.Message)
cc.Abort()
Finally
MesgBox("Closed the Client")
End Try
When i run the above, I've noticed in the log file for the service (in the system32 folder on my server) that 2 requests are made each time - presumably one for where I am trying to add a record and the other I would think would be the request for the ID of this member (which isn't created, hence why I believe it it is simply returning the last successful entry in the table).
I know there isn't a problem with the actual web service as there is another user successfully able to add to the db via the service (unfortunately I am unable to simply copy their set-up as they are hitting it via a php page) so i know there is a problem somewhere in my code.
Is cc.CreateMember(newMem) the correct syntax for passing a member's details to the function in the webservice is what I am wondering?

I've re-wrote the code (seems identical to above) and republished the web service. Seems to be working OK now so I must have had some silly mistake somewhere!

Related

Why does MembershipProvider.GetUser consume so many resources how to ensure it uses the EF db context?

In our web application, we observed the following:
GetUser/CreatMembershipEntities/ExplicitLoadFromAssembly seems quite expensive.
Also noticing that CreateEntityConnection is being called - EntityFramework?
I'm not entirely convinced that EF was configured correctly for this application. If it was, and was in use, I wouldn't expect to see new connections to be initiated for every call - yes/no?
Is a way to streamline this to avoid some major code refactoring?
The use of System.Web.Security.Membership.GetUser() seems like a biggie here. Instead of using the MembershipProvider to create users, what about just executing a sproc that does the same things.
I have found the following code that is ridiculous, as far as I am concerned - in causing a new call for each user until a unique one can be generated:
For i As Integer = 1 To Integer.MaxValue
'Generate unique username
If System.Web.Security.Membership.GetUser(userName & i) Is Nothing Then
'Increment value until no duplicate username found
userName = userName & i
Exit For
End If
Next
-- UPDATE--
I have modified the question slightly...
We were able to run up to 20 users then the IIS server would tank. Does the GetUser() method create a brand new connection every time? It looks like it, based on the results. How can I ensure that this GetUser() thing is actually using the db context, rather than spinning up its own connections?

Is it necessary that Data Source of connection string must match the system name

This is my first post to this precious website. I am a new learner of vb.net. I am working on a simple purchase project, where i got some errors. But the first thing is which baffled me is:
This is my connection string at module level, on the developed machine.
Public strCn As String = "Data Source = (local); Initial Catalog = PSys; Integrated Security = false; User ID = sa; Password = 123;"
Is it mandatory that Data Source must be the original name of the System Name. I mean If i use (local) or using ( . ), so will it work or not? Because when i copy my project to any other system for further development so every time i need to change the Data source, otherwise i get the error that: "Network-related or instance-specific error occurred......."
Kindly guide me that what i need to do.
When you are developing an application which uses a database server such as MsSQL it is not wise to install the server along with your application in every pc which is installed to. For example what are you going to do if a customer has a local network with 10 computers? Are you going to install SQL server in all 10 of them? And if so what if they need to share data?
So your best approach (based on common practice by other applications) will be to allow the user to install the SQL server where he wants and let him configure your application and point it to the server's location. If you follow that path then the configuration of your application can be in the setup application or in the application itself.
Now about the development phase, I had a similar situation in which I needed to develop the same application in two different computers. What I did was to install the SQL server in both of them with a named instance "sqlexpress" then in the application I used the
Data.SqlClient.SqlConnectionStringBuilder
class to build the connection string. I did something like this:
Public Function getDevConnectionString() As String
Dim csb As New Data.SqlClient.SqlConnectionStringBuilder(My.Settings.dbConnectionString) '<-My original cs in app settings
csb.DataSource = My.Computer.Name & "\sqlexpress"
Return csb.ConnectionString
End Function
Whenever I need a connection string I simply call getDevConnectionString() which returns the connection string based on the computer name plus the sql server instance name. For example:
Dim cs As String
#If DEBUG Then
cs = getDevConnectionString()
#Else
cs = getReleaseConnectionString()
#End If
where getReleaseConnectionString() is the function that returns your connection string configured by the customer.
Hope this point you the right direction...

Reporting Server throws an error for RunEmbeddedQuery method for XML data source

This the scenario have. There's an SSRS server that has a report where the datasource is of type XML and it uses windows authentication, nothing else to it. Inside the report there's a dataset that uses that data source with this for a query "=Code.ReportUser.GetListOfItems()". This calls a method in the custom assembly that connects to the database and returns data in a string formated like this (angle brackets changed to curly for read
"<Query><XmlData><Items>" + xmlDocument.DocumentElement.InnerXml + "</Items></XmlData></Query>"
where sql datatable is written into the xmlDocument. If I go to the reporting server through an IE and run the report everything works as it should. The Problem occures when add this link to Zangle application which runs it as "IEHOST.app 'report's url'". I believe its a foxpro app that opens a browser object and report fails on the dataset that uses my xml data source. There's no question about url or reports correctness because it functions in a different environment.
This is the server error i get:
library!ReportServer_0-8!ca0!02/24/2012-10:18:45::
Call to GetPermissionsAction(path to my report).
library!ReportServer_0-8!e68!02/24/2012-10:18:45::
Call to GetSystemPropertiesAction().
library!ReportServer_0-8!e68!02/24/2012-10:18:45::
Call to GetPropertiesAction(path to my report, PathBased).
library!ReportServer_0-8!10bc!02/24/2012-10:18:45::
Call to GetSystemPermissionsAction().
library!ReportServer_0-8!e68!02/24/2012-10:18:45::
Call to GetSystemPropertiesAction().
processing!ReportServer_0-8!10bc!02/24/2012-10:18:45::
e ERROR: Throwing Microsoft.ReportingServices.ReportProcessing.ReportProcessingException: ,
Microsoft.ReportingServices.ReportProcessing.ReportProcessingException:
Error during processing of the CommandText expression of dataset ‘Items’.;
processing!ReportServer_0-8!10bc!02/24/2012-10:18:45::
e ERROR: Throwing Microsoft.ReportingServices.ReportProcessing.ReportProcessingException: ,
Microsoft.ReportingServices.ReportProcessing.ReportProcessingException:
Cannot set the command text for dataset 'Items'. ---> Microsoft.ReportingServices.ReportProcessing.ReportProcessingException:
Error during processing of the CommandText expression of dataset ‘Items’.
at Microsoft.ReportingServices.OnDemandProcessing.RuntimeDataSet.RunEmbeddedQuery(Boolean& readerExtensionsSupported, Boolean& readerFieldProperties, List`1 queryParams, Object[] paramValues)
--- End of inner exception stack trace ---;
I'm not sure what this means exactly. Any thoughts? it looks like a permission issue but i don't understand where. I did try to change xml data source authentication from windows to none and then add my AD account as an execution user on the reporting server. This didnt' change anything still working from browser but from Zangle browser object. One more thing, server requires authentication and all the report regardless of the environment promt for login and successfully authenticate so my credentials seems to pass to the server and only my xml data source is throwing an error when launched from with Zangle. Please share your ideas. I'm a programmer but I'm not too server stuff savy and I'm new to SSRS. Thank you.
Resolved. Turns out that foxpro app lowercases everything and the name of the sql server passed to the assembly doesn't match the name stored in the assembly. Silly :) So we'll be lowercase comparing everything from now on.

When to close the result set (Basic ODBC question)

I am working on some small project for the local firm and the following code runs fine on my machine, but it produces errors on their server. Currently I don't have access to that server, and this is not a field that I know a lot about, so I have to ask you guys.
The page is written in the classic ASP (javascript for scripting).
The logic goes like this:
conn.Open("myconnection");
bigQuery = "...";
rs = conn.execute(bigQuery);
while (!rs.eof) {
...
smallQuery = "..."
rssmall = conn.execute(smallQuery);
...
rssmall.close();
...
rs.movenext();
}
rs.close();
conn.close();
As I said this runs fine on my machine, but it returns some error (the worst thing is that I don't even know what error) on company's server if bigQuery returns more than ~20 rows. Is there something wrong with my code (this really isn't my field, but I guess it is ok to gather data in the loop like this?), or is there something wrong with their IIS server.
Thanks.
edit:
More info:
It 's Access database. Everything is pretty standard:
conn=Server.CreateObject("ADODB.Connection");
conn.Provider="Microsoft.Jet.OLEDB.4.0";
conn.Open("D:/db/testingDb.mdb");
Queries are bit long, so I wont post them. They are totally ordinary selects so they aren't the issue.
I had a legacy Classic ASP application which I inherited that was very similar (big queries with other queries running within the loop retrieving the first query's results) that ran fine until forty or more records were returned. The way I "solved" the problem was to instantiate another connection object to run the other query. So using your pseudo code, try --
conn.Open("myconnection");
conn2.Open("myconnection")
bigQuery = "...";
rs = conn.execute(bigQuery);
while (!rs.eof) {
...
smallQuery = "..."
rssmall = conn2.execute(smallQuery);
...
rssmall.close();
...
rs.movenext();
}
rs.close();
conn2.close();
conn.close();
What server are they actually running?
Most newer versions of Windows Server don't actually come with the Jet 4.0 driver for 64 bit at all so you can't use an access database with that driver if your app runs as a 64 bit app. You can try running as 32 bit which might solve the problem.
There is an alternative driver packaged as an office component which may be an option.
Try writing a simple test page that literally opens and closes the database connection like so:
<%
Dim conn
Set conn = Server.CreateObject("ADODB.Connection")
conn.Provider = "Microsoft.Jet.OLEDB.4.0"
conn.Open("D:/db/testingDb.mdb")
Response.Write("Database Opened OK")
conn.Close()
%>
Run this on the production server and if you see Database Opened OK then you'll know it's definitely the query rather than the database causing the issue.
If you get an error trying to open the database then you need to changed to using the newer driver or try the app in 32 bit mode
In the case that it is the query causing the issue then it may be that you'll need to use the various additional arguments to the Open() method to try using a different cursor (forward only if you only need to iterate over the results once) which will change how ADODB retrieves the data and hopefully mediate any performance bottleneck related to the query.
Edit
If you want to try debugging the code a bit more add the following at the start of the file. This causes the ASP script processor to continue even if it hits an error
On Error Resume Next
Then at intervals throughout the file where you expect an error might have happened do
If Err <> 0 Then
Response.Write(Err.Number & " - " & Err.Description)
End If
See this article from ASP 101 for the basics of error handling in ASP and VBScript

WebSharingAppDemo-CEProviderEndToEnd Queries peerProvider for NeedsScope before any files are batched to the server. This seems out of order?

I'm building an application based on the WebSharingAppDemo-CEProviderEndToEnd. When I deploy the server portion on a server, the code gives the error "The path is not valid. Check the directory for the database." during the call to NeedsScope() in the CeWebSyncService.cs file.
Obviously the server can't access the client's sdf but what is supposed to happen to make this work? The app uses batching to send the data and the batches have to be marshalled across to the temp directory but this problem is occurring before any files have been batched over. There is nothing for the server to look at to determine whether the peerProivider needs scope. What am I missing?
public bool NeedsScope()
{
Log("NeedsSchema: {0}", this.peerProvider.Connection.ConnectionString);
SqlCeSyncScopeProvisioning prov = new SqlCeSyncScopeProvisioning();
return !prov.ScopeExists(this.peerProvider.ScopeName, (SqlCeConnection)this.peerProvider.Connection);
}
I noticed that the sample was making use of a proxy to speak w/ the CE file but a provider (not a proxy) to speak w/ the sql server.
I switched it so there is a proxy to reach the SQL server and a provider to access the CE file.
That seems to work for me.
stats = synchronizationHelper.SynchronizeProviders(srcProvider, destinationProxy);
vs.
SyncOperationStatistics stats = syncHelper.SynchronizeProviders(srcProxy, destinationProvider);