I have a RESTful WCF service that accesses a SQL Server database. Using it I can access the database when it runs on IIS Express, but when it runs on local IIS, it returns nothing from the database!
Here is the the method in the contracts:
[OperationContract]
[WebGet(UriTemplate = "/getdata",
BodyStyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json)]
List<DbData> getData();
and here is the web.config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<connectionStrings>
<add name="AlamalConStr"
connectionString="Data Source=.; Initial Catalog=trial_web_service_db;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<authentication mode="Windows" />
<identity impersonate="false" />
</system.web>
<system.serviceModel>
<services>
<service name="AlamalBankWCFService.AlamalService">
<endpoint kind="webHttpEndpoint" contract="ServiceLib.IAlamalService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="wsHttpBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<directoryBrowse enabled="true" />
</system.webServer>
</configuration>
When I run this WCF service on IIS Express, it returns the data from the database, but when I host it on Local IIS and run it it does not return data from database it shows empty page with [] only!
You might have to check the userid of your app pool. Check with that app pool user id has access to connect to SQL server. Either add the app pool id to sql server or change connection string to use SQL authentication. i.e. Use user id and password in connection string for a user created in sql server.
Some more help here.
http://msdn.microsoft.com/en-us/library/ff648340.aspx
Related
When I execute the consuming application it is giving me the below exception:
The requested service, 'https://localhost:53996/HistoricStatementsWS.HistoricStatements.svc' could not be activated.
and when I try to enter this path into chrome it says:
A registration already exists for URI 'https://ws20.intra.local:53996/HistoricStatementsWS.HistoricStatements.svc'.
I don't know how to get rid of these exceptions and I have been through a lot of forums so far.
SERVER-SIDE app.config
<system.web>
<compilation debug="true" />
<membership defaultProvider="ClientAuthenticationMembershipProvider">
<providers>
<add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />
</providers>
</membership>
<roleManager defaultProvider="ClientRoleProvider" enabled="true">
<providers>
<add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" />
</providers>
</roleManager>
</system.web>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding">
<security mode="Transport">
<transport clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="behaviourHttps" name="HistoricStatementsWS.HistoricStatements">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding"
name="wsHttpEndpoint" contract="HistoricStatementsWS.IHistoricStatements" />
<endpoint address="HistoricStatementsWS.HistoricStatements.svc"
binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding"
name="mexEndpoint" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="https://localhost:53996/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="behaviourHttps">
<useRequestHeadersForMetadataAddress />
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"
httpsGetUrl="https://localhost:53996/HistoricStatementsWS.HistoricStatements.svc"
policyVersion="Policy15" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
CLIENT-SIDE Webconfig
<configuration>
<configSections>
</configSections>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.webServer>
<directoryBrowse enabled="true" showFlags="Date,Time,Extension,Size" />
</system.webServer>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpoint">
<security mode="Transport">
<transport clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint behaviorConfiguration="endpointBehavior" address="https://localhost:53996/HistoricStatementsWS.HistoricStatements.svc" binding="wsHttpBinding"
bindingConfiguration="wsHttpEndpoint" contract="IHistoricStatements.IHistoricStatements"
name="wsHttpEndpoint" />
</client>
<behaviors>
<endpointBehaviors>
<behavior name="endpointBehavior">
<clientCredentials>
<clientCertificate storeLocation="LocalMachine" storeName="My" findValue="00B192126A72D282D2" x509FindType="FindBySerialNumber"/>
<serviceCertificate>
<authentication certificateValidationMode="None" revocationMode="NoCheck" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
For anyone with same problem I managed to solve the issue by directing my ip 127.0.0.1 to my full domain name: computername.intra.local. I changed localhost in the server's web config to my domain name (computername.intra.local) and removed the domain prefix from httpsGetUrl since the baseAddress is used also for this value so https://localhost:53996/ was duplicated. Although there is still duplicate values and the config is still not accurate, at least the wsdl is accessible from the browser. The browser (on my local) asks for a certificate and authenticates successfully.
However I still lack the know how of reaching the same url from a different machine on the same network. I installed the root and client certificates as they are on my local machine and still it gives this error: 'The HTTP request was forbidden with client authentication scheme 'Anonymous'.' I was having this error on my local from the client side but solved it by calling the certificate programmatically. The same code on the new machine does not work.
The code is:
WSHttpBinding httpBinding = new WSHttpBinding(SecurityMode.Transport);
httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
httpBinding.Security.Message.NegotiateServiceCredential = false;
httpBinding.Security.Message.EstablishSecurityContext = false;
var httpUri = new Uri("https://ws12.intra.local:53996/HistoricStatementsWS.Historicstatements.svc");
var httpEndpoint = new EndpointAddress(httpUri, EndpointIdentity.CreateDnsIdentity(""));
var newFactory = new ChannelFactory<IHistoricStatements>(httpBinding, httpEndpoint);
newFactory.Credentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySubjectName, "ws12.intra.local");
newFactory.Credentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectName, "ws12.intra.local");
I must add that no proxies are used, 'Anonymous' is switched on in IIS with user IUSR, root folder has full permissios to IUSR, IIS_IUSRS, Network, Network Service. I first wish to connect from the browser on new machine as this gives error:
403 -Forbidden: Access is denied. You do not have permission to view
this directory or page using the credentials that you supplied.
Your replies are much appreciated.
Justin
I've been struggling with this for a couple of days now - I cannot get this WCF service configured correctly to use a custom membership provider. When I fire up the test client I get this error:
The username/password Membership provider MidlandsCoop.MembersWcfService.Business.UserAuthentication specified in the configuration is invalid. No such provider was found registered under system.web/membership/providers.
I have been following this MSDN link to no avail. Can anyone tell me where I'm going wrong?
Here's my web.config:
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="MyCS" connectionString="Data Source=my server;Initial Catalog=MyDB;Integrated Security=True" providerName="System.Data.SqlClient"/>
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBinding">
<security>
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="MidlandsCoop.MembersWcfService.MembersService" behaviorConfiguration="Service_Behaviour">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration=""
name="basicHttpBinding" contract="MidlandsCoop.MembersWcfService.IMembersService" />
<endpoint binding="wsHttpBinding" bindingConfiguration="wsHttpBinding"
name="wsHttpBinding" contract="MidlandsCoop.MembersWcfService.IMembersService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Service_Behaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom"
membershipProviderName="MidlandsCoop.MembersWcfService.Business.UserAuthentication" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
</configuration>
My user authentication class is as follows:
public class UserAuthentication : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
if (null == userName || null == password)
{
throw new ArgumentNullException();
}
var db = new PetaPoco.Database("MyDB");
db.Fetch<dynamic>("SELECT Username, Password FROM MyTable WHERE Username=#0 AND Password =#1",
userName, password);
}
}
Any suggestions would be greatly appreciated.
the link that you have provided mentions customUserNamePasswordValidatorType to specify custom authentication type, UserAuthentication in your case. I think MembershipProviderName should be a class derived from MembershipProvider Class.
I have a WCF rest webservice that runs fine on my local VS2010 environment, but when deployed to IIS 6.0 on windows server 2003, I get the HTTP Error 404 - File or directory not found.
I've searched other threads with similar questions and tried all the suggestions to no avail.
Here's my service contract:
[ServiceContract]
public interface IRestServiceImpl
{
[OperationContract]
[WebInvoke(Method = "PUT", ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "Execute")]
ExecuteResponse Execute(ExecuteRequest request);
[OperationContract]
[WebInvoke(Method = "PUT", ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "ExecutePutJSON")]
ExecuteResponse ExecutePutJSON(ExecuteRequest request);
}
The implementation code behind (RestServiceImpl.svc.cs) is as follows:
public class RestServiceImpl : IRestServiceImpl
{
public ExecuteResponse Execute(ExecuteRequest request)
{
//processing code that returns ExecuteResponse
}
public ExecuteResponse Execute(ExecuteRequest request)
{
//processing code that returns ExecuteResponse
}
}
The RestServiceImpl.svc is as follows:
<%# ServiceHost Language="C#" Debug="true" Service="CICJIS.IWS.RestServiceImpl"
CodeBehind="RestServiceImpl.svc.cs" %>
The Web.config:
<configuration>
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing">
<listeners>
<add name="messages" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="messages" />
</listeners>
</source>
</sources>
<sharedListeners>
<add name="messages"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="C:\Logs\RestService.svclog" />
</sharedListeners>
<trace autoflush="true" />
</system.diagnostics>
<system.web>
<compilation debug="true" defaultLanguage="c#" targetFramework="4.0" />
<httpRuntime maxRequestLength="999999" maxQueryStringLength="999999"
executionTimeout="999"/>
</system.web>
<system.serviceModel>
<diagnostics>
<messageLogging
logEntireMessage="true"
logMalformedMessages="true"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true"
maxMessagesToLog="3000"
maxSizeOfMessageToLog="10000000" />
</diagnostics>
<services>
<service name="RestServiceImpl" behaviorConfiguration="ServiceBehavior">
<endpoint address="" binding="webHttpBinding" contract="IRestServiceImpl"
behaviorConfiguration="web">
</endpoint>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
I have tried the following:
1.) installed the ASP.net 4.0 using aspnet_regiis -i
2.) Ran C:\WINDOWS\Microsoft.NET\Framework\v3.0\Windows Communication Foundation>Service
ModelReg.exe -i
3.)manually changed the .svc extension mapping in the properties of the website for .svc to point to c:\windows\microsoft.net\framework\v4.0.30319\aspnet_isapi.dll
4.)In directory security unchecked the integrated windows authentication.
5.)Changed the ASP.net version from 2.0 to 4.0 on the website properties.
I have another WCF SOAP webservice deployed to the same server and IIS and I can browse and connect to it fine. I don't understand why I am unable to browse this WCF rest service or connect to it.
Any help is appreciated!!
Thanks in advance!
Ok, I solved my issue. I just re-ran the following steps a couple of times and it seemed to have fixed my problem. I am able to get to my Rest webservice now.
installed the ASP.net 4.0 using aspnet_regiis -i
Ran C:\WINDOWS\Microsoft.NET\Framework\v3.0\Windows Communication Foundation>Service ModelReg.exe -i
I've just generated the installer for a WCF Service and I'm trying to use:
The structure installed at the wwwroot is the following:
http://bit.ly/11zZ85E
In the bin folder are included all dlls in which the service depends. The class that implements the service contract is defined in one of those dll. All generation and instalation proccess is all good. And I have on the IIS Manager the following:
http://bit.ly/10xBI3Y
The issue is that when I try to access the wsdl at the browser I'm only able to see:
<%# ServiceHost Language="VB" Debug="true" Service="MyApplication.ServiceImplementation.LicensingService" CodeBehind="MyApplication.ServiceImplementation.Service.vb" %>
And If I try to use the Add Service Reference from a Visual Studio project I see this:
There was an error downloading
(ServiceAddress)/$metadata
The request failed with HTTP status 404: Not Found.
Metadata contains a reference that cannot be resolved:
(ServiceAddress)
The remote server returned an unexpected response: (405) Method Not Allowed.
The remote server returned an error: (405) Method Not Allowed.
If the service is defined in the current solution, try building the solution and adding the service reference again.
The installer I did was generated with Installshield 2010.
Here is my Web.Config
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation strict="false" explicit="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.serviceModel>
<services>
<service name="MyApp.ServiceImplementation.Service" behaviorConfiguration="WSSecurityBehavior">
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address="Operations" binding="wsHttpBinding" contract="MyApp.ServiceContracts.IService" />
<endpoint binding="wsHttpBinding" name="mex" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WSSecurityBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="WSSecurityBinding">
<reliableSession enabled="true" ordered="true" />
</binding>
</wsHttpBinding>
</bindings>
<!--protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping-->
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<directoryBrowse enabled="true" />
<handlers accessPolicy="Read, Script" />
<defaultDocument>
<files>
<clear />
<add value="Service.svc" />
</files>
</defaultDocument>
<httpErrors>
<clear />
</httpErrors>
</system.webServer>
</configuration>
I developed small WCF service which takes all records from table. It looks like that:
IService1.cs:
[ServiceContract]
public interface IService1
{
List<badanieCis> GetRecords();
}
Service1.svc.cs:
public List<badanieCis> GetRecords()
{
przychodniaEntities dataContext = new przychodniaEntities();
return dataContext.badanieCis.ToList();
}
And I am getting a message: Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata
What I have made after some research was changing markup in svc file for this one:
<%# ServiceHost Language="C#" Debug="true"
Service="Harvesting.Service.HarvestingService" CodeBehind="Service1.svc.cs" %>
But still nothing.
My web.config file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
<connectionStrings>
<add name="przychodniaEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string="data source=DAREK-PC\SQLExpress;initial catalog=przychodnia;integrated security=True;multipleactiveresultsets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
You are missing service definition in the config file. You need something like:
<services>
<service behaviorConfiguration="..." name="Service1 with namespace">
<endpoint address="..." name="..." binding="wsHttpBinding" bindingConfiguration="...." contract="IService1 with unterface" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
<services>
...
You may use this tool to help with config.