Feeds:
Posts
Comments

Archive for the ‘.NET’ Category

I am writing a bit of .NET/C# code to add a SHA1 hash to a PDF file. Since I’m not a .NET specialist, I am slowly making my way through the .NET API’s. And since the documentation is not always as clear or expliciet as I would like to see it, I’ll ask the question here: the two methods in the sample class below are functionally equal, but is the one using the ‘BufferedStream‘ the best way to make sure that a large file will not gobble up all memory when there are multiple hashings ongoing on a single server? Or is there an even better way?

using System;
using System.IO;
using System.Security.Cryptography;

public class Sha1Hashing
{
    public String getHash( string FilePath ) {
        HashAlgorithm sha = new SHA1CryptoServiceProvider();
        String hashAsBase64 = "";
        byte[] dataArray;

        if ( File.Exists( FilePath ) ) {
            dataArray = File.ReadAllBytes( FilePath );
            byte[] hashvalue = sha.ComputeHash( dataArray );
            hashAsBase64 = Convert.ToBase64String( hashvalue );
        }
        return hashAsBase64;
    }

    public String getBufferedHash( string FilePath ) {
        HashAlgorithm sha = new SHA1CryptoServiceProvider();
        String hashAsBase64 = "";

        FileInfo fi = new FileInfo( FilePath );
        if ( fi.Exists && ( fi.Length > 0 ) ) {
            FileStream FS = new FileStream( FilePath, FileMode.Open, FileAccess.Read );
            BufferedStream BS = new BufferedStream( FS );

            using ( BS ) {
                byte[] hashvalue;

                BS.Seek( 0, SeekOrigin.Begin );
                hashvalue = sha.ComputeHash( BS );
                hashAsBase64 = Convert.ToBase64String( hashvalue );
            }
        }
        return hashAsBase64;
    }
}

PS. You know how to add your own namespace, and you know how to create unit tests in Visual Studio, don’t you?

Read Full Post »

I have been spending way too much time over this issue already, so I appreciate all the help I can get on this: why does this CAML query NOT work in SharePoint 2010?

SPQuery q = new SPQuery();
q.Query = "<Where><Eq><FieldRef Name='Name'></FieldRef>"
q.Query = q.Query + "<Value Type='Text'>somepage.aspx</Value></Eq></Where>";
SPListItemCollection aspx = sitepageslibrary.GetItems( q );

(PS. I had to reformat the code a bit in order to fit it into this blog post; in my live code, the query string is on a single line)

When I say it does not work, I mean that the ‘aspx‘ collection does contain a collection after the ‘GetItems( q )‘ call… But when inspecting its contents in the VS debugger, however, even the ‘Count‘ property contains an error message, and there are no ‘SPListItem‘s to be found.

Just to be clear: the code runs in an ‘SPFeatureReceiver‘, in a sandboxed solution. If I do not specify the CAML query, then the code runs fine and I can iterate over the pages in the library. And yes, I have tried the query on other fields than ‘Name‘, with the same lack of success.

So:

  • Is there an error in my CAML query?
  • Is there something wrong with my approach?
  • Is there a problem with the SitePages library?

I have changed my strategy and may well not need the answer to my questions in order to get my feature working… but I do want to understand what is going wrong in what seems to be a very simple situation!

Read Full Post »

I’m currently attending an ‘Advanced Developer’ training for SharePoint 2010, so I think it’s a good idea to keep track of some of the tools that can help with SharePoint development. If I’m to believe Google, this SharePoint Developer Tools list on Listly seems to be the ‘best’ overview. ‘CKS – Development Tools Edition for Visual Studio‘ and ‘ULS Viewer‘ were already mentioned and used during our training, by the way. I’m pretty sure there are versions of these for SharePoint 2013 as well.

Some of the tools mentioned are hardly specific to Sharepoint, though, and would be better catalogued as ‘web developer tools’. Oh well, if that helps new SharePoint developers to pick up a few serious tools…

Read Full Post »

Creating a SharePoint 2010 custom field type isn’t too hard, but… not all is well in the result I managed to put together a few days ago. I tried to limit the display and input length of an “asp:TextBox” using the standard ASP attributes “MaxLength” and “Columns”, with no visible result in the New Item form. SharePoint 2010 obviously “overrides” some of the standard behavior of the “asp:TextBox”…

After a bit of experimentation I found a way to get at least a partial solution: using the “size” attribute with a CSS value in “em” is rendered in SharePoint 2010 as a “style=’width:…em’” attribute on the “<input>” element. I still have to find a way to limit the number of characters to be entered, though. Suggestions are welcome!

PS. No, I don’t want to use Javascript to get what I want – SharePoint and ASP.NET must be able to do better than this, don’t they?

Read Full Post »

Today I created my first ever custom field type for SharePoint 2010 – and it worked first time around as well, just needing an extra IISRESET to clear all caches.

I must admit that I closely followed the MSDN Walkthrough: Creating a Custom Field Type for this particular development, but I did create my own type, and not the ISBN in the Walkthrough. The Walkthrough is very thorough, and clearly succeeds in accompanying a Visual Studio newbie like me to a successful deployment.

I could only find one flaw: the Walkthrough does not explain the reasons (if any) behind the naming of the files and classes for the solution. Perhaps that will become clear as I go further down this SharePoint development road.

Sidenote: the hardest part of the whole development had nothing to do with the code, but with Visual Studio 2010. Apparently Visual Studio 2010 accesses the SharePoint (configuration and content) databases with the user account of the developer. That means that MS SQL Server has to be told to allow that, regardless of the access rights you have for the SharePoint farm / site collection / sites etc. Me thinks there are better ways to make sure that only real developers can unleash VS2010 onto SharePoint 2010!

Read Full Post »

Just a quick note: I did finally find the time to re-test the ntlmHTTP project for ColdFusion after the installation of .NET 3.5 on our ColdFusion test server (check out my earlier posts on the subject). And yes, ntlmHTTP works – at least for accessing web pages that are protected by “Windows Integrated Authentication”. Next trials will try to access SharePoint 2010…

Read Full Post »

My ‘DotnetRuntimeEnvironment’ component for ColdFusion managed to surprise me: after installing the .NET framework 3.5 the ‘GetSystemVersion()‘ method still returned ‘2.0.50727‘, rather than the ‘3.5‘ or so I expected. It took some digging to find a decent explanation, but the reason appears to be mundane (at least for .NET experts): my component actually returns the version for the Common Language Runtime (CLR), and not for the whole framework (thank you, Jon Skeet!). The CLR is the runtime for the bytecode, comparable to the JVM in the Java universe.

This also means that more is needed to tell the exact .NET framework version you’re actively using – I suppose that trying to instantiate a class that first appeared in a given framework version would be a sufficient indicator. Oh well, back to the coding board, eh?

For completeness sake I can report that the code I published last week continues to work when multiple versions of .NET (CLR and/or framework) are installed on your machine.

Read Full Post »

I have been testing the ‘DotnetRuntimeEnvironment’ component I wrote about a week ago. Doing so also pointed to a better, more robust version. Here it is (the » symbol again means you should put what follows on the preceding line):

<cfcomponent name="DotnetRuntimeEnvironment" >

  <cfset VARIABLES.noruntime = "NORUNTIME" />
  <cfset init() />

  <cffunction name="init" access="private" returntype="void" output="false" >
    <cftry>
        <cfset VARIABLES.re = CreateObject( "dotnet",
             » "System.Runtime.InteropServices.RuntimeEnvironment" ) />
      <cfcatch type="any" >
        <cfset VARIABLES.runtime = "" />
      </cfcatch>
    </cftry>
  </cffunction>

  <cffunction name="isRunning" access="public" returntype="boolean" output="false" >
    <cfreturn IsObject( VARIABLES.runtime ) />
  </cffunction>

  <cffunction name="GetRuntimeDirectory" access="public" returntype="string" output="false" >
    <cfif IsObject( VARIABLES.runtime ) >
      <cfreturn VARIABLES.runtime.GetRuntimeDirectory() />
    <cfelse>
      <cfreturn "NONE" />
    </cfif>
  </cffunction>

  <cffunction name="GetSystemVersion" access="public" returntype="string" output="false" >
    <cfif IsObject( VARIABLES.runtime ) >
      <cfreturn VARIABLES.runtime.GetSystemVersion() />
    <cfelse>
      <cfreturn "NONE" />
    </cfif>
  </cffunction>

</cfcomponent>

This version will run on any platform, and give a reasonable answer for any method called – even when no .NET runtime can be found. The ‘isRunning()‘ method allows you to check  the existence of a .NET runtime before you try to work with other methods. As always, suggestions or additions are welcome!

Read Full Post »

I have had a bit of trouble to get ntmlHTTP running correctly on our servers. In response to my ticket on RiaForge, Nick Harvey clarified the dependence of the DLL on .NET version 3.5 (or higher, I suppose). I’m not a Windows nor a .NET specialist, and I don’t have many rights on the servers at work, so it took me and my collegue a bit of time to conclude that we were trying to run Nicks code on a .NET 2.0 base – and that didn’t work out, of course.

I already have a few ColdFusion pages with diagnostics about our servers, so I decided to do the right thing and add the .NET version to the existing diagnostics. It took me a while to find the exact class and method in the .NET runtime, but it turned out to be simple. So I have created a small ColdFusion CFC to help me (the » symbol means you should put what follows on the preceding line):

<cfcomponent
   name="DotnetRuntime" >

   <cfset VARIABLES.re = CreateObject( "dotnet",
             » "System.Runtime.InteropServices.RuntimeEnvironment" ) />

   <cffunction
      name="GetRuntimeDirectory"
      access="public"
      returntype="string"
      output="false" >

      <cfreturn VARIABLES.re.GetRuntimeDirectory() />

   </cffunction>

   <cffunction
      name="GetSystemVersion"
      access="public"
      returntype="string"
      output="false" >

      <cfreturn VARIABLES.re.GetSystemVersion() />

   </cffunction>

</cfcomponent>

Once you have that component, it’s pretty simple to use it – just put this in a .CFM (I’m supposing you have called your CFC ‘DotnetRuntime.cfc‘ in the current directory):

<cfsilent>
    <cfset dotnet = CreateObject( "component", "DotnetRuntime" ) />
</cfsilent>

<cfoutput>
   <html>
   <body>
      <h1>Dotnet Runtime Environment</h1>

      <p>
         This ColdFusion server is currently running <b>.NET version #dotnet.GetsystemVersion()#</b>
         from directory '<code>#dotnet.GetRuntimeDirectory()#</code>'
      </p>
   </body>
   </html>
</cfoutput>

So there you have it. I know this works in our setup, but I don’t know what will happen when there are multiple .NET runtimes on your machine… That’s why I wrapped the code into a CFC –  functions to detect specific versions of .NET, handle multiple runtimes, etc. can thus be added in a single component for easy versioning and maximum reuse. Suggestions or additions are welcome!

PS. I have left the “hint” attributes out of the code above, because I haven’t yet found a good way to publish program code in WordPress.

Read Full Post »

We have been trying out the 0.2 version of the ntlmHTTP project for ColdFusion, in order to see if we could call the SharePoint webservices. Unfortunately, POSTing a SOAP request never works: we always end up with a nasty error message for any of the new methods. Here’s a sample message:

System.MissingMethodException:
Could not find the generic method Com.Bluemini.CF.NetHttpRequest.setUsername

Decompiling the .class files that ColdFusion generates to integrate the DLL shows that the methods are there, just like a CFDUMP of the object we create. But CF8 (on a Windows 2003 server) seems unable to call them… I’ll download the source code and pass it on to our local .NET guru for examination. I’ll keep you posted about the results of our investigations (that may take a few days, though).

Read Full Post »

At work, we have tried the initial version of the ntlmhttp project on RiaForge (see my post from last week as well). We’re (still!) on CF8, installed in a minimal way, so I had to install the .NET integration layer first. But that is fairly simple:

When that is done, you just download the ntlmHTTP component.

  • Put the DLL on your file system, and write down the path.
  • Now run this script to check your installation:
    <cfset NetRequest = CreateObject( "dotnet", "Com.Bluemini.CF.NetHttpRequest", "/path/to/your/NetHttpRequest.dll") />
    <cfdump var="#NetRequest#" />

So far, so good: calling a (secured) webpage worked too. From the almost non-existent documentation it isn’t clear to me how we might use this to issue a SOAP request – we’ll see about that later.

When trying out the component with a web service call, I need to remember not to add the domain prefix to the username required in the call parameters. That’s different from what we need for our CFHTTP calls, but not too hard to do. I just wonder: is it the component that makes it possible to skip the domain name, or is it the configuration of our Windows network?

Read Full Post »

NUKLEOS weblog

Read a balanced view of a complex and delicate matter: Picking a Winner: .NET vs. J2EE (Software Development Online at http://www.sdmagazine.com).

Read Full Post »