Featured Post

SQL Query in SharePoint

The "FullTextSqlQuery" object's constructor requires an object that has context but don't be fooled. This context will no...

Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Thursday, January 17, 2013

Document.ReadOnly (Office 2007) does not consider checked in documents

If you have ever worked with word add-ins there will have been a point in time where you would have needed to determine whether a document is read only or not. There is a boolean property on the Document class called ReadOnly.

With the introduction of SharePoint documents can be read-only if they have not been checked out. Word 2010 takes this into account however Word 2007 can out before SharePoint and does not cater for this. If your document is not checked-out (making it read only), the ReadOnly property will return false in Word 2007.

The way we resolved this issue is by creating an method on our webservice which indicates whether a document is checked out or not. This helps us determine whether we can allow the user to edit the document. Remember that forcing check outs on documents in libraries is configurable so remember to check this setting first.


if (!spListItem.ForeCheckout)
{
   return false;
}


if (file.CheckOutType == SPFile.SPCheckOutType.None)
{
   return false;
}

return true;




Wednesday, January 9, 2013

How to copy one PackagePart to another

One of the most used functions in my xml utilities class is the one that copies the contents from one PackagePart to another. It's simple but if you don't know how here's a easy code snippet :)

public static void CopyContents(PackagePart packagePartIn, PackagePart packagePartOut){

  using (Stream outputStream = packagePartOut.GetStream(FileMode.Create, FileAccess.Write))  {

    using (Stream stream = packagePartIn.GetStream())    {

      byte[] contents = new byte[stream.Length];      stream.Read(contents, 0, contents.Length);
      outputStream.Write(contents, 0, contents.Length);
    }
  }
}

Friday, September 9, 2011

Create a custom WCF NET.TCP service

I recently learned about creating a custom net.tcp service. I thought I'd make a nice step by step post on how to do this. Also, I'd just to note that this a standard WCF service example hosted in IIS 7.

Ok, so this is how to create a super simple net.tcp service

1.
Firstly, create a server application. In this example my server is a simple class library project. Now the only thing you'll need in this project are 4 files (see image). You will also need to add a reference to System.ServiceModel.











 2. UploaderService.svc 

This file needs to contain your servicehost tag. Set the "Service" value to that of your service class (including the namespace) and if you're deploying to the gac, set the assembly information otherwise. In this example I'm going to use CodeBehind. Here is an example of what your svc file should look like:


3. IUploaderService.cs

Add the ServiceContract attribute to your interface and make sure that all methods have the OperationContract attribute as well.

 4. UploaderService.svc.cs

This is your service class. Nothing fancy needs to happen here, just make sure your service implements your interface and you add all required methods. I added a Ping method that returns a simple boolean to help during setting up and debugging.



5. Web.Config

You can either apply settings to your service via code or via configuration settings. In this example I will demonstrate via the configuration settings. There are thousands of settings you can use but I am going to show you the most basic example you will ever need just to get your service working.


so you could literally copy this exact xml doc and just change the address for the service to wherever you plan on deploying it.

6. IIS Setup

So that's the server side code. To deploy the code, drop your svc, config and dll (in a bin folder) into a folder and add it as a virtual directory in a website. 


Last step for your service is to add the net.tcp as an enabled protocol and setup your bindings for your virtual directory. See images below for settings:


Now check whether your service is pingable via http.


7. Calling your service from the client application.

You can use one of the service utils to generate some client code to use in your client application but mine isn't working so I just copied the interface from my server to my client (if the interface ever changes you'd have to regenerate a new client file anyways so might as well just copy paste). I then use the interface to create a System.ServiceMode.ChannelFactory instance pointing to my service. Here is a code example:

Your client configuration will look similar to the server except that you won't need the service behaviour settings and instead, add the .net version type in the supportedRuntime setting.

 
Run your application and see if you can ping your service.

8. Debugging

If you receive any errors, you can add diagnostics to your config file that will give you more detailed information about the exception that is occurring between the client and the server. Add the following xml to your client application which will output a file in your bin which you can open using the svc tools.



9. Tips

So I made a very silly mistake this week. My web application was set to .NET 2 and my client was set to .NET 4. This obviously did not work so please make sure that the application pool that you are running your site under has the same .NET version as your client application.

Secondly my service's platform was set to 32 bit and my client's was 64 bit. This was also a problem so make sure that they are both built for the same platform.

10. The End

I hope this post helps you. If there is anything I might have missed please let me know and happy net.tcp.ing :)


Monday, May 30, 2011

Why does my image become smaller when inserting into Word?

I recently rewrote a report generation system which used to create word documents in Word (running on the server) to a new system which generates these reports in OpenXML. The report output from the new system had to completely match the output from the old system. One of the discrepencies we found was that some images that were being inserted were larger than those in the old system.

With a little investigation I found out that when inserting images into Word, it scales them down to 96 DPI (If larger). One specific image was 300 DPI so when inserting it using OpenXML is was MUCH larger than in the Word Generator output. I've been working with word for 7 years and I've never noticed or knew that this happened!!! Maybe I'm the only one but I thought this was rather interesting - hence this post.
So if you need your OpenXML code to insert your images the same way Word does here is some code to change the dpi of an image if its greater than 96:

Monday, March 7, 2011

Issues with AltChunk

I managed to find the underlying problem to a rather annoying bug using AltChunk. I've generated thousands of reports using OpenXml but this one word document would always break xml markup of the document when inserting it using AltChunk.

After stripping the document to only contain the parts that broke it I managed to find out that the "DocumentSettingsPart" contained some elements called SmartTagType. I've never seen these before and not sure what they are used for but the moment I removed them from the document my AltChunk insertion started to work so I now remove them from all my documents before I insert using AltChunk.

I wonder if this is a known bug - will ask on the forum.

Here's some code:

// Get a list of smart tags in the document settings part and remove these
List<SmartTagType> smartTags = mainDocumentPart.DocumentSettingsPart.Settings.Descendants<SmartTagType>();

// Loop backwards otherwise the elements orders change
for (int i = smartTags.Count - 1; i >= 0; i--)
{
  smartTags[i].Remove();
}