Sharepoint: publish a webservice with your solution

February 29, 2008

In this article I’ll cover how can you publish a WebService with your solution that will be accessible at every site in all the web applications where the solution is deployed. To keep thing simple, I’ve chosen a simple Helloworld webservice but with this approach we could publish any webservice or .aspx pages or a httpHandler

What we will do is to publish the service in the _vti_bin sharepoint folder of our site. To do this, we must first copy the .asmx file of the service in the Common FilesMicrosoft Sharedweb server extensions12ISAPI folder of our server.

<%@ WebService Language=”c#” Class=”MyAssembly.Services.HelloWorldService,MyAssembly.Services”%>

This was the .asmx file we want to distribute and following is the .DDF file from which we’ll generate the solution, I’d like to show that you could also publish a web.config file for the _vti_bin/MyAssembly folder, we would want to do so if, for example, were deploying an httpHandler instead of a webservice or if we need to configure some AppSettings parameters.

; Solution.DDF
FeaturesISAPIMyAssemblyweb.config ISAPIMyAssemblyweb.config
FeaturesISAPIMyAssemblyHerramientas.asmx ISAPIMyAssemblyHelloWorldService.asmx
ServicesbinDebugMyAssembly.Services.dll MyAssembly.Services.dll

Then we must define the manifest.xml file used in the solution deployment:

<RootFiles>
<RootFile Location=ISAPIMyAssemblyweb.config />
< RootFile Location=ISAPIMyAssemblyHelloWorldService.asmx />
</RootFiles>

<Assemblies><Assembly DeploymentTarget=WebApplication Location=MyAssembly.Services.dll /></Assemblies>

Remember to set the appropiate assembly permission at the CodeAccessSecurity section of the manifest.xml file if not running under Full Trust mode or not deploying the assembly in the GAC.

Finally, here is the easy code of our Helloworld service:

namespace MyAssembly.Services
{
    [WebService(Namespace = "http://MyAssembly.com/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class HelloWorldService : System.Web.Services.WebService
    {

        [WebMethod]
        public string HelloWorld()
        {
            return "Greetings from this Service !";
        }

    }
}

Now, after deploying the solution we can access the webservice adding _vti_bin/MyAssembly/HelloWorldService.asmx at our site url (for those sites we have deployed the solution to !). However, If we have deployed the solution in the GAC, the service should be able to all the sites in the server.

That’s all for now ! As always, feel free to comment anything you might find interesting !

Advertisements

Deploy a XML file in your Sharepoint Solution to the Web Application Folder

February 27, 2008

This is a small trick I’ve been using these days in a Sharepoint Solution in order to add a xml file with some data which some webpart will read later on a Sharepoint site and make use of it. There are many ways to accomplish this each one with it’s benefits and drawbacks.

The first approach I thought of was to deploy the xml file in the _layouts folder and then query the data using a WebClient request from my webpart, the problem I found is that if anonymous access wasn’t enabled for the site, the request failed with a 401 Unauthorized exception because the ASP.Net credentials where the ones used by default to access the resource. One solution was to enable the impersonation at the web.config file of the application and then, the current user’s credentials would be used instead, but as I didn’t know where my solution would be deployed and didn’t have any control over the web.config file configuration, I rejected this approach.

Finally, I decided to deploy locally the xml file in the bin folder of the application and then accessing it with a simple StreamReader. The first problem was how to deploy the file ? Finally, I found the small trick I was talking about, you can deploy any file from a Sharepoint Solution in the bin folder of the web application just by doing the same as you do with a normal assembly .dll file, with the <Assembly> tag in the manifest.xml file:

<Assemblies><Assembly DeploymentTarget=WebApplication Location=MyData.xml /></Assemblies>

When the Solution is deployed, the xml file will be copied to all the bin folders of the selected web application. This raises the obvious drawback of this approach: There’s one xml file for each web application and there’s no easy way to globally manage them.
Since we will be accessing the xml file from our webpart, and assuming we haven’t set our trust level to Full (because we know it’s a bad thing to do!), we must grant our assembly the FileIOPermission  in order to be able to read the file. We can do this in the manifest.xml with the following section:

<CodeAccessSecurity><PolicyItem><PermissionSet class=NamedPermissionSet version=1 Description=Permission set for OurAssembly><IPermission class=System.Security.Permissions.FileIOPermission version=1 Unrestricted=true /> </PermissionSet><Assemblies><Assembly Name=OurAssembly /></ Assemblies></PolicyItem></CodeAccessSecurity>

Please note that I’ve set the unrestricted=true attribute just to keep it simple but you should set the Read attribute to the appropiate folder.Now, we can read the file from our webpart:

string loc = HttpContext.Current.Server.MapPath("/") + "bin\";
using (StreamReader reader = new StreamReader(loc + @"MyData.xml"))
{
    XDoc = XDocument.Load(reader, LoadOptions.None);
}

And that’s all, with this approach we can deploy all kinds of xml data and even .dll configuration files or any other localresource you might need. I hope it’s helpful and don’t forget to leave a comment if so !