Wednesday 29 April 2009

HTTP Error 401.1 - Unauthorized: Access is denied due to invalid credentials.

Are you getting this message when you are trying to access to anothers class from your webservice?:

HTTP Error 401.1 - Unauthorized: Access is denied due to invalid credentials

First thing to do:

1-Start a command prompt.

2-Locate and then change to the directory that contains the Adsutil.vbs file. By default, this directory is C:\Inetpub\Adminscripts.

3-Type the following command, and then press ENTER:

cscript adsutil.vbs set w3svc/NTAuthenticationProviders "NTLM"

4-To verify that the NtAuthenticationProviders metabase property is set to NTLM, type the following command, and then press ENTER:

cscript adsutil.vbs get w3svc/NTAuthenticationProviders

5-The following text should be returned:NTAuthenticationProviders : (STRING) "NTLM"

The second thing to do:

1-To solve this problem the best way is go to IIS->default site->your webservice virtual folder
2-Right click->properties-.directory security->edit
3-Be sure that everything is like this:




If you still having problems, just fllow this KB from Microsoft (Good luck)
http://support.microsoft.com/kb/871179

System.IO.FileNotFoundException: The Web application at http://xxxxx could not be found. Verify that you have typed the URL correctly

Have you have this problem? probably because you try to call the object SPSite from a webservice. I assume you get this error:

System.IO.FileNotFoundException: The Web application at http://panshare-cl01 could not be found. Verify that you have typed the URL correctly. If the URL should be serving existing content, the system administrator may need to add a new request URL mapping to the intended application.
at Microsoft.SharePoint.SPSite..ctor(SPFarm farm, Uri requestUri, Boolean contextSite, SPUserToken userToken)
at Microsoft.SharePoint.SPSite..ctor(String requestUrl)
at Service.WebServiceDescription() in c:\Inetpub\wwwroot\SiteManager\App_Code\Service.cs:line 57

It is quite scary...but there is a easy way to fix it.

Basically if you doing this call SPSite mySite = new SPSite(http://panshare-cl01/);
Your webservice that in this case is located in he port 88, in a different pool it will fail because it doesn't have the authentification for SQL Server and as any sharepoint developer knows Sharepoint is a bunch of websites kept in Sql Server, and if this one doesn't run properly Sharepoint becomes useless.


Anyway, the issue is a satabase security problem so in order to solve it, just do the following;


1- Go to IIS
2- Web Sites
3- Default Web Site
4- If the webservice is located here...so to the webservice ,ie: SiteManager
5- Right click->Properties
6- Change the "Application pool" from "DefaultAppPool" to "Sharepoint - 80"


Have a look:

Tuesday 14 April 2009

Copying data (on the fly) from one Document to another in one Add-in.

If you are interested in copy a word document file, binary style, you will find plenty of problems copying a document on the fly. To sort that out the only way we have, it is to do it is by copying the file locally OR by using this method, what basically is the clipboard.

As soon as we managed to keep the data in the clipboard we can tranform this document into binary and do whatever we want with it....

Mind that this has been developed for an Office Add-in, so it should be incorporated into the event:

private void Connect_DocumentBeforeSave(Microsoft.Office.Interop.Word.Document Doc, ref bool SaveAsUI, ref bool Cancel)

in the Connect.cs class

//## The before save event is disable to avoid recursive savings...
((Microsoft.Office.Interop.Word.Application)applicationObject).DocumentBeforeSave -= new Microsoft.Office.Interop.Word.ApplicationEvents4_DocumentBeforeSaveEventHandler(Connect_DocumentBeforeSave);

//## Temp file where we will keep the new document.
object newDocPath = (object)System.IO.Path.GetTempFileName();

//## Initialize a bogus parameter for arguments we don't care about
object oMissing = System.Reflection.Missing.Value;

//## We find the doc and we get a clean copy...we dont need to do this but it is quite useful.
this.Document = ((Microsoft.Office.Interop.Word.Application)applicationObject).Documents.Application.ActiveDocument;

//## Select entire contents, and copy to clipboard
Document.ActiveWindow.Selection.WholeStory();
Document.ActiveWindow.Selection.Copy();

//## Create new document and paste from clipboard
Microsoft.Office.Interop.Word.Document newDoc = ((Microsoft.Office.Interop.Word.Application)applicationObject).Documents.Add(ref oMissing, ref oMissing,ref oMissing, ref oMissing);

//## We paste all the stuff...
newDoc.ActiveWindow.Selection.Paste();

//## Saving new document....
((Microsoft.Office.Interop.Word.Application)applicationObject).ActiveDocument.SaveAs(ref newDocPath,
ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);

//## Closing the file to avoid problems.
newDoc.Close(ref oMissing, ref oMissing, ref oMissing);