I have a small sharepoint project which integrates into a larger sharepoint project. My project uses two web services. I've added them using Web Reference (embedded in the Service Reference) dialog in VS2010. We have two sets of web services - one for testing and one for production. When I deploy the app locally, the web services settings are written to the web.config file located at C:\inetpub\wwwroot\wss\VirtualDirectories\80\ on my local machine. The section looks something like this -
<applicationSettings>
<XXX.YYY.Properties.Settings>
<setting name="XXX_YYY_ZZZ_WS1" serializeAs="String">
<value>http://<TEST_IPAddress>/WebService/WS1.asmx</value>
</setting>
<setting name="XXX_YYY_ZZZ_WS2" serializeAs="String">
<value>http://<TEST_IPAddress>/WebService/WS2.asmx</value>
</setting>
</XXX.YYY.Properties.Settings>
</applicationSettings>
The difference between the test and production web services is just the IP Address. When I change the IP address to production, the app is not using the new values. I had to go back to VS, update the Web Reference URL in the Properties dialog to the correct production urls, then re-deploy the package again. This is tedious as I constantly keep switching from test to production web service url's. I want to be able to change the IP address in the app.config, refresh the page in the browser and it should pick up the new urls.
Am I doing something wrong? Is there another way to do this?
I think if you change the webservice url in code then you will not have to repeat the build process. you can change like this
WebServiceObjectName webService = new WebServiceObjectName ();
webService.Uri = [IPaddress or DNS name]
We do this like so:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IPublicWS"
openTimeout="00:00:05"
sendTimeout="00:03:00"
receiveTimeout="00:10:00"
closeTimeout="00:00:30"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="262144" maxBufferPoolSize="524288" maxReceivedMessageSize="262144"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="131072" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<!-- Production -->
<endpoint name="SvLive" address="http://sv.com/PublicWS/PublicWS.svc/PublicWS" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IPublicWS" contract="SV.IPublicWS" />
<!-- Test -->
<endpoint name="SvTest" address="http://staging.sv.com/PublicWS/PublicWS.svc/PublicWS" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IPublicWS" contract="SV.IPublicWS" />
</client>
</system.serviceModel>
Then, to get a client reference to this webservice:
public static PublicWSClient Client()
{
#if PRODUCTION
return new PublicWSClient("SvLive");
#else
return new PublicWSClient("SvTest");
#endif
}
Which is called like:
var sv = PublicWSClient.Client();
This prevents any of the manual steps you describe, and allows both test and live to be captured in a single config file ready to be checked in.
Related
I'm using Visual Studio for a school project and I'm to create a simple WCF Service Application web service that I need to test using WCF Test Client.
I developed the service, but then when I run the debugger, it opens a web browser, I copy the link to the IService1.svc file, and try to add that to the test client, and it fails complaining it cannot get meta data.
I tried this on a fresh solution with a new project, and same thing.
My Web.config file:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.8.1" />
<httpRuntime targetFramework="4.8.1"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
Am I missing any steps in testing the web services?
Depending on your wcf configuration file, you can see the parts without endpoints and service contracts. You may have missed the <service.model> section:
<services>
<service name="Namespace.Service1">
<endpoint address="" binding="basicHttpBinding" contract="Namespace.IService1" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
I am using vs2013 and vs2015 and cannot remove the service references:
a normal right click and then delete show do the job (or the delete key on the keyboard when selected)
But I get:
The configuration for the service reference could not be deleted due to the following issue: An error occurred creating the configuration section handler for system.serviceModel/bindings: AssemblyResolveEvent handlers cannot return Assemblies loaded for reflection only.
Here is the part of my web.config (line 249 and more)
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="PayPalAPISoapBinding">
<security mode="Transport" />
</binding>
<binding name="PayPalAPIAASoapBinding">
<security mode="Transport" />
</binding>
<binding name="PayPalAPISoapBinding1" />
<binding name="PayPalAPIAASoapBinding1" />
<binding name="PayPalAPISoapBinding2">
<security mode="Transport" />
</binding>
<binding name="PayPalAPIAASoapBinding2">
<security mode="Transport" />
</binding>
<binding name="PayPalAPISoapBinding3" />
<binding name="PayPalAPIAASoapBinding3" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://api.sandbox.paypal.com/2.0/" binding="basicHttpBinding" bindingConfiguration="PayPalAPISoapBinding" contract="PayPalSvc.PayPalAPIInterface" name="PayPalAPI" />
<endpoint address="https://api-aa.sandbox.paypal.com/2.0/" binding="basicHttpBinding" bindingConfiguration="PayPalAPIAASoapBinding" contract="PayPalSvc.PayPalAPIAAInterface" name="PayPalAPIAA" />
<endpoint address="https://api.sandbox.paypal.com/2.0/" binding="basicHttpBinding" bindingConfiguration="PayPalAPISoapBinding2" contract="PayPalLive.PayPalAPIInterface" name="PayPalAPI1" />
<endpoint address="https://api-aa-3t.sandbox.paypal.com/2.0/" binding="basicHttpBinding" bindingConfiguration="PayPalAPIAASoapBinding2" contract="PayPalLive.PayPalAPIAAInterface" name="PayPalAPIAA1" />
</client>
</system.serviceModel>
I referenced the WSDL from paypal years ago and rebuild the whole thing using the nuget package (REST instead of the old soap api)
But I cannot cleanup the old wsdl code and (service)references.
I got the same error if I deleted the web.config part and deleted the reference afterwards.
Steps to manually fix it:
Removed the client and bindings part from the system.serviceModel in the web.config manually.
Removed the service reference dir from the filesystem
manually edited my *.csproj file. (Searched for paypal and removed everything except the new nuget reference. Also removed the "service reference" reference from the csproj.)
Delete web.config then delete the service reference.
Restore the web.config afterwards and clean up any binding references.
I created a wcf service using VS2010 and it works correctly, when I run it from VS2010, but when I deploy it on IIS 6(according this post), It does not work.
I did this steps:
I created a folder in my server(C:\WCFServices\HRService) and copied HRService.svc and web.config to it and grant full access to this folder for ASPNET user.
I created a Bin folder in the above folder and copied my service dll in it.
I Created new virtual directory in my default web site(HR):
My .svc files , web.Configs are as below:
My .svc file
<%# ServiceHost Language="C#" Debug="true" Service="HumanResourceService.HRService" %>
And my web.Config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="NewBinding0" />
</basicHttpBinding>
</bindings>
<services>
<service name="HumanResourceService.HRService">
<endpoint address="" binding="basicHttpBinding"
bindingConfiguration="" contract="HumanResourceService.IHRService" >
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
But when I want to access my WCF service via IE I get this error:
Could anyone tell me, what is the problem?
Make sure the the name for the service in the configuration file matches the .svc file. In your posted code it doesn't. Your .svc file has "HumanResourceService.HRService", so the name attribute for the <service> element should match:
<service name="HumanResourceService.HRService">
Also, is this a RESTful service or SOAP? I ask because you are using the webHttpBinding for your service, which is for REST. If it's not, I suggest basicHttpBinding or wsHttpBinding.
If it is REST, then add this to the behavior section of your config file:
<endpointBehaviors>
<behavior name="webBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
I found the problem.
In IIS and in Web Service Extensions section, the ASP.NET V4.0.30319 status was Prohibited and I changed it to Allowed and the problem solved.
I am trying to get the Windows User name of the client who is accessing the ASP.NET page that is being hosted on my Local IIS. I am callign a WCF service within the ASP.NET page which returns the windows username of the client. I came across so many posts regarding and most of them are suggesting that
OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name
HttpContext.Current.User.Identity.Name
HttpContext.Current.User.Identity.Name
should work. The problems I am facing is "1" is always returning Null. "2" and "3" are always returning my local user name and not the requesting user's name. Am I missing anything in the web.configs of both ASP.NET and WCF service.
IIS properties: Integrated Windows authentication Enabled.
Here is the code.
WCF
public string GetWindowsUser()
{
string temp = OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name;
string temp1 = HttpContext.Current.User.Identity.Name;
string temp2 = HttpContext.Current.User.Identity.Name;
return "Temp: "+temp+" \nTemp1: "+temp1+" \nTemp2: "+temp2;
}
WEB.Config
<system.web>
<compilation debug="false" targetFramework="4.0"/>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService1" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
<message clientCredentialType="UserName" algorithmSuite="Default"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:4772/Services.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1" contract="WindowsAuthServices.IService1" name="BasicHttpBinding_IService1"/>
</client>
</system.serviceModel>
ASP.NET Page:
protected void Page_Load(object sender, EventArgs e)
{
WindowsAuthServices.Service1Client client = new WindowsAuthServices.Service1Client();
lblWelcome.Text = client.GetWindowsUser();
}
Web.Config
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService1" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
<message clientCredentialType="UserName" algorithmSuite="Default"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:4772/Services.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1" contract="WindowsAuthServices.IService1" name="BasicHttpBinding_IService1"/>
</client>
</system.serviceModel>
This is because your call is done on behalf of the identity under which the ASP.Net worker process runs and not under the identity of the user requesting the page (which is called impersonation).
From http://geekswithblogs.net/robz/archive/2007/10/03/wcf-impersonation---specifying-windows-authentication-credentials-on-the-service.aspx
1) The ASP.NET client web.config file needed to have impersonation set using the following markup (I put it under the authentication element as shown):
<authentication mode="Windows"/>
<identity impersonate="true"/>
2) The service behavior had to be configured to use Windows for permissions and to impersonate callers.
<serviceBehaviors>
<behavior name="XXX.XXXXXXXXXXXX">
<serviceMetadata httpGetEnabled="True"/>
<serviceAuthorization principalPermissionMode="UseWindowsGroups" impersonateCallerForAllOperations="true" />
</behavior>
</serviceBehaviors>
Our enterprise wants its site to open only those using company
devices(laptops). So they want the sharepoint site to use Windows
authentication and not prompting the username and password. If the
windows username matches with the one in the list of approved users it
should open or else redirect to different authentication page. getting
1st part done has been a problem.
So you just need your laptops to be connected to windows domain and use Integrated security and set correct security groups in Sharepoint.
What you describe is not security and it will never work.
Sounds like you need to implement/configure your website for identity delegation. If you need to configure WCF for delegation, check out this MSDN article.
I finally found the solution. When the other user are trying to access my local IIS using IP, my local IIS assumes that it is an internet request and not intranet request and since its windows authentication, it works only with intranet requests. To solve this I had to host my website on one of our domain servers. Since the domain server was already setup such that only users in that domain can access it, now it has the windows login info. And there ends my misery.
I have two versions of the same proof-of-concept site: The unsecure version:
http://www.tlsadmin.com/tlsadmin/PortalHome.aspx
and the secure version:
https://www.tlsadmin.com/tlsadmin/PortalHome.aspx
The problem I have is that my WCF-Based web services don't seem to work under HTTPS. Is there something I'm missing, or not understanding about this? I thought a relative URL for the SVC file would cover everything
<asp:ScriptManager ID="ScriptManager1" runat="server" >
<Services>
<asp:ServiceReference Path="~/Services/Contacts.svc" />
<asp:ServiceReference Path="~/Services/Domains.svc" />
<asp:ServiceReference Path="~/Services/TreeViewNavigation.asmx" />
<asp:ServiceReference Path="/Services/FullSoaSchedulerService.svc/json" />
</Services>
</asp:ScriptManager>
Perhaps I need to add an additional binding for the webservice to work over HTTPS?
<service name="LC.www.nexthop.mx.POC.grid_WebService.Domains">
<endpoint address="" behaviorConfiguration="LC.www.nexthop.mx.POC.grid_WebService.DomainsAspNetAjaxBehavior"
binding="webHttpBinding" contract="LC.www.nexthop.mx.POC.grid_WebService.Domains" />
</service>
You want to add a custom binding to your configuration to enable it for HTTPS by setting your binding's security mode to transport.
<bindings>
<webHttpBinding>
<binding name="httpsBinding">
<security mode="Transport">
</security>
</binding>
</webHttpBinding>
</bindings>
The default security mode is None which doesn't play well with HTTPS.
Then assign that binding to your endpoint:
<service name="LC.www.nexthop.mx.POC.grid_WebService.Domains">
<endpoint address="" behaviorConfiguration="LC.www.nexthop.mx.POC.grid_WebService.DomainsAspNetAjaxBehavior"
binding="webHttpBinding" bindingConfiguration="httpsBinding" contract="LC.www.nexthop.mx.POC.grid_WebService.Domains" />
</service>
This blog post helped me out when I first ran into this situation.
Hope this helps!!