Wrong SPContext in Wcf Service - wcf

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?

Related

WCF RIA services and WSDL generation

Need help on an issue I am having. I inherited this WCF RIA project and am trying to understand a couple of things.
When I publish the project, how does the WSDL get generated and put on the URL that I published to?
And I want to incorporate FaultException handling so as to transmit the exceptions to the client side. I read some stuff regarding the FaultException on the web and was able to get a small sample working with the regular WCF service.
I thought it would be similar within my actual project. But unfortunately I am running into some issues(probably due to my lack of WCF + RIA services knowledge).
So in my actual project my Context class derives off of LinqToEntitiesDomainService.
I created a new ContextFaultException class which had some methods to capture some custom error messaging.
Then I applied the [FaultContract(typeof(ContextFaultException))] to some of the methods in my Context class. Everything compiles and all is fine. But when I published to a website and then when I added this service reference to the client, I don't see my new ContextFaultException in the Reference.cs file that's generated.
I thought may be moving it within the Context class will solve the issue. So I made my ContextFaultException class as an inner class of this Context class but I am running into some other issues. Before I try to figure out these issues, I just want to know if this the right approach?
Any suggestions/pointers??
TIA
The URL must be formatted to get to the namespace wdsl
for example:
namespace My.Namespace.Services
{
[EnableClientAccess()]
public partial class MyClassName : LinqToEntitiesDomainService<XXX>
{
....
}
}
Then use the following pattern for the url
http://YOURHOST/APP/Services/My-Namespace-Services-MyClassName.svc?wsdl
Use "-" for the "."

How to access a Service Reference from JavaScript?

(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).

Windows Authentication WCF and ASP.Net MVC2: getting users AD info to a wcf webservice

Hello there fellow StackOverflow and programming enthusiasts. I have a question, I am trying to move an MVC website that I created over to a test server so that users can start testing... I have run into a little issue that I overlooked when I developed the site. My website calls a service that I wrote that takes takes the service callers AD user name and uses it to do some back end work...
private string CallerNameOnly = string.Empty;
private string CallerFullDomain = string.Empty;
public ACOService()
{
this.CallerFullDomain = OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name.ToString();
this.CallerNameOnly = this.CallerFullDomain.Substring(this.CallerFullDomain.IndexOf('\\') + 1);
}
This worked just perfectly when I was developing on my local machine and my username was passed into the service just fine... However, I am having a hard time replicating the same functionality when I deploy to a server that I am using... For some reason, the current user ends up being my machine name...
Now, I seemed to have isolated the issue to a setting in IIS 7 that when changed, changes the behavior of my website somewhat... If I go to the app pools advanced settings and I change the Process Model/Identity field, from LocalSystem, to any of the other Identity's It changes who the user is... My remote debugger kept bugging out on me so I couldn't figure out what the user name was, but you get the idea?
My question is, how do I get the username of the person using my website (which uses windows authentication) to call my web service with the username he used to access my site? I thought about getting the username and passing it directly into a constructor ie...
public ACOService(string userID)
{
this.CallerNameOnly = userID;
}
but that presents problems, because I already have a constructor with a string in it. And I think I would have to place the constructor into my contract wouldn't I? How would that work in WCF anyway?
Any help with this problem would be greatly appreciated.
You need to impersonate the client on the service.
http://msdn.microsoft.com/en-us/library/ms731090.aspx

Creating a log for WCF operations / getting app directory

I want my WCF service to log errors / operations, etc.
I have a very simple logging class but finding the directory to create / write to is returning a null reference exception:
public static string Path()
{
return Path.GetDirectoryName
(Assembly.GetEntryAssembly().Location);
}
This works in say a console app but not WCF, perhaps there is a different convention?
Or alternatively are there any simple libraries for logging in WCF?
WCF has built-in message logging, following links should help you.
http://msdn.microsoft.com/en-us/library/ms730064.aspx
http://geekswithblogs.net/mnf/archive/2008/10/03/use-wcf-message-logging.aspx
http://mkdot.net/blogs/dejan/archive/2008/10/23/wcf-tracing-and-message-logging.aspx

Get listing of web services referenced in WCF application?

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.