Could anyone out there give some pointers on how to go about getting a listing of all the web service references used by a WCF application - the pseudo code I'm envisioning might look something like:
For each ws in MyWebServices
Console.WriteLine("Service Name: " & ws.Name)
Next
How to build the MyWebServices object is what I am wondering?
Thanks
You should be able to do:
ClientSection clientSection = (ClientSection)ConfigurationManager.GetSection("system.serviceModel/client");
foreach(ChannelEndpointElement channelEndpointElement in clientSection.Endpoints)
{
// Use any of the channel endpoint element properties here:
// Address, BehaviorConfiguration, Binding, BindingConfiguration, Contract, etc.
}
You could just check the configuration file. All WCF services used by the application should be in the client section.
Related
I'm consuming a WCF service in my project for which I've added the reference using 'Add Service Reference...'. I expected it to generate a clean proxy with a ServiceClient entity and the Interface. Instead, I see that it has created a MethodNameRequest, MethodNameRequestBody, MethodNameResponse, MethodNameResponseBody entities for each OperationContract method.
So while invoking the service methods, the proxy passes to the service method an instance of MethodNameRequest with the input parameters of the method as the properties of the RequestBody. See below an example of a call to AboutInformationGet() method which doesn't accept any parameters.
public WCFDynamicInvocation.PostingService.AboutModel AboutInformationGet() {
WCFDynamicInvocation.PostingService.AboutInformationGetRequest inValue = new WCFDynamicInvocation.PostingService.AboutInformationGetRequest();
inValue.Body = new WCFDynamicInvocation.PostingService.AboutInformationGetRequestBody();
WCFDynamicInvocation.PostingService.AboutInformationGetResponse retVal = ((WCFDynamicInvocation.PostingService.IMIGQPosting)(this)).AboutInformationGet(inValue);
return retVal.Body.AboutInformationGetResult;
}
I believe this behavior is what one would expect to see in a Webservice Proxy. Hence I suspect that the WCF service is not properly configured.
Did someone here face this issue? What would be the change to be done at the service so that the proxy generated is similar to the WCF service.
Cheers.
There is a similar post here.
Right click your service reference -> Configure service reference... -> Check if "Always generate message contracts" check box is checked. Uncheck it and hit OK to regenerate the proxy to see if you get a normal proxy.
After struggling with this for some time, I've finally found that the cause for the message contracts in the proxy was the service interface had the following attribute:
[XmlSerializerFormat(Use = OperationFormatUse.Literal, Style = OperationFormatStyle.Document)]
As I understand, I could decorate the DataContracts with the following attribute to avoid wrapping
[MessageContract(IsWrapped = false)]
but the response still gets wrapped as the OperationContract hasn't been modified.
As there were no particular need to use XMLSerializer in place of WCF's default DataContractSerializer, we would remove the XmlSeralizerFormat decoration.
(WCFDS = WCF Data Services 5,backed by Entity Framework, using oData v3, formatted as JSON, served up via IIS7 and protected by Windows authentication.)
The crux is accessing the WCFDS in an authenticated manner from an AJAX call.
To this end, I have a client as an ASP.Net Web Application with Windows authentication set in Web.config and a Service Reference pointing to the WCFDS.
I want to use client-side JavaScript to access the Service Reference. How can I do this?
I thought about creating an aspx page, hosting in the client and direct calls from JavaScript code to this page, which would then retrieve data through the Service Reference - but I'm at a loss over how to expose the full functionality of the Service Reference in this manner (there are dozens of entities).
Can anyone help with advice?
The Windows authorization settings in web.config are not directly related to WCF Data Services, so you probably won't need to set anything there. You WILL need to set your settings up properly in IIS.
There are a number of good articles out there about using Windows authorization over WCF Data Services; in a nutshell you have a wide degree of freedom in how you choose to expose authorization (ranging from filtering out individual entities from a feed to throwing 401/403s).
A couple of good articles to read through:
http://msdn.microsoft.com/en-us/data/gg192997
http://blogs.msdn.com/b/astoriateam/archive/2010/07/21/odata-and-authentication-part-7-forms-authentication.aspx (yes, I know that's forms auth but the auth part of this is entirely orthogonal to what the code looks like in your WCF Data Services)
http://blogs.msdn.com/b/astoriateam/archive/2010/07/19/odata-and-authentication-part-5-custom-httpmodules.aspx
The simplest code you could possibly write would be something along the lines of:
namespace Scratch.Web
{
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class ScratchService : DataService<ScratchContext>
{
[QueryInterceptor("Products")]
public Expression<Func<Product, bool>> ProductsAuthorization()
{
if (!HttpContext.Current.Request.IsAuthenticated)
{
return (p) => false;
}
return (p) => HttpContext.Current.User.IsInRole("AllowAccessToProducts");
}
// ...rest of service code...
}
}
Note that everything on the client side is controlled by the browser, so you don't really need to do anything there (the biggest step might be to add the site to Trusted Sites so it doesn't prompt you for your credentials if you're on a domain-joined machine).
I'm looking for the correct way to have redundancy for a WCF service. I think I'm trying to solve a "infrastructure" issue in code. I'm not up to speed on load balancers but it seems like there should be something like routers to exactly this.
// Cycle through the list of service.
foreach (var uri in InfrastructureInformation.ServiceUris)
{
try
{
using (var client = WcfClientFactory.Create<ServiceClient>(uri))
{
// Do stuff here.
}
}
catch
{
// todo: Do not catch "exception" here. We have to find a better way of doing this.
// Try the next URI.
}
}
Seems like there should be a way to have one URI that I could hit that some "balancer" would hand off to an available service. If one service goes down for maintenance then the balancer would just not give any request to that service.
Now I know about WCF routing and I thought well that's the answer. Just put up a WCF router and have it hand out the connection but what happens if it falls over? Doesn't this give you a single point of failure? I'm looking for something more industrial.
WCF in .NET 4.0 has a routing capability that can be used in a failover scenario like you describe. This WCF sample shows how the built-in RoutingService class can be used for this purpose.
You could have a look at Microsoft Network Load Balancing (aka NLB). Microsoft also mention this in the context of WCF. There is an article on this here.
I have SharePoint 2010 (_http://sp2010/, for instance). I have created site (_http://sp2010/site/) and WCF Service, which is hosted in ISAPI folder. In service I have such test method:
[OperationContract]
public string GetCurrentWebUrl()
{
return SPContext.Current.Site.Url + " | " + SPContext.Current.Web.Url;
}
I call service from my console application using this address - _http://sp2010/site/_vti_bin/WcfService.svc/mex. When calling method GetCurrentWebUrl I expect to get _http://sp2010/site/, but I always get _http://sp2010/. In other words SPContext is not correct.
What am I doing wrong? How can I get right context?
Can you double check that you are really calling http://sp2010/site/_vti_bin/WcfService.svc/mex? When using the Visual Studio Add Service Reference dialog, it usually uses the root, as in http://sp2010/_vti_bin/WcfService.svc/mex.
If you are setting it up in code it should indeed work, at least it does for me :(
What is SPContext.Current.Web.Url and Web.ID? Does that match the /site/ Web?
I have a service that exposes multiple endpoints. One beeing wsHttp and the other Net.Tcp. Is there any way I can know which one the clients used to make the call inside the service method ?
Thanks !
You can use the OperationContext object to retrieve the channel information
if (OperationContext.Channel.LocalAddress.Uri.Scheme == Uri.UriSchemeHttp)
{
// Called by wsHTTP
}
else if (OperationContext.Channel.LocalAddress.Uri.Scheme == Uri.UriSchemeNetTcp)
{
// Called by NetTcp
}
...
Yes. If you look at the following property you should be able to tell where things came in from.
OperationContext.Current.EndpointDispatcher.EndpointAddress