ﻁ DevExpertise

DevExpertise

Practical tips and tricks for all things .NET, SharePoint, Silverlight, InfoPath, and general application development.

kamagra kaufen paypal vardenafil posologie generique cialis 20mg preis kamagra vente viagra belgique cialis pris viagra rezeptfrei apotheke acheter cialis tadalafil vendita di cialis online purchase viagra
tadalafil 5 mg levitra mg costo cialis quanto costa in farmacia levitra pris cialis 5mg filmtabletten preisvergleich kamagra si vende farmacia comprar levitra contra reembolso en españa sites fiables kamagra achat levitra belgique comprar viagra western union

SharePoint 2010 Wallpapers

Posted by DevExpert on May 12th, 2010

Not sure why, but any time I build a virtual machine I like to set its wallpaper to something that looks good, yet also identifies what the purpose of the virtual machine is.  I recently just built a SharePoint Server 2010 virtual machine, and I wanted a good-looking SharePoint 2010 wallpaper for it, but couldn’t find a thing online.  Since I’m no stranger to Photoshop, I decided to just make my own.  Here’s what I came up with:

SharePoint Server 2010

SharePoint 2010 Wallpaper 1

SharePoint 2010 Wallpaper 2

SharePoint 2010 Wallpaper 3

SharePoint 2010 Wallpaper 4


SharePoint Foundation 2010

SharePoint Foundation 2010 Wallpaper 1

SharePoint Foundation 2010 Wallpaper 2 

SharePoint Foundation 2010 Wallpaper 3

SharePoint Foundation 2010 Wallpaper 4

 

If you’re interested, you can download them from the following location.  Enjoy!

Tags: ,
Posted in SharePoint 2010 | 3 Comments »

Implementing a LINQ version of SQL’s LIKE Operator

Posted by DevExpert on September 25th, 2009

One of the requirements of one of my recent projects was to implement a search page which allowed the user to enter a search term that supported wildcards.  The search term could contain any number of wildcards in any position within that term.

If you’ve done anything like this before, you probably know there’s nothing built-in to LINQ that supports this type of behavior.  Sure, you could use a combination of String.StartsWith, String.EndsWith, or String.Contains, but this could quickly become too cumbersome if there are many wildcards and/or they are scattered throughout the search term.  Let’s look at a couple simple examples to illustrate…

Pretend for a second I was doing this in SQL, and I needed to get all values that start with the letter T.  I would do this:

select * from SomeTable where SomeField LIKE 'T%'


The .NET/LINQ equivalent would be this:

var results = (from v in values where v.StartsWith("T") select v);


Not too difficult.  However, what if you wanted to do the SQL-equivalent of this:

select * from SomeTable where SomeField LIKE '%a%a%'


You’d have do a little creative parsing.  It gets even worse when you as the developer doesn’t know what search term will be entered, how many wildcards will be included, and where in the term they appear.  It all has to be dynamic.

I did a little poking around to see if anyone has done this before, and the only thing I could find was recommendations on using StartsWith/EndsWith/Contains, which I already ruled out.  I also found the SqlMethods.Like() method which sounded perfect.  However after further research, discovered it can only be used on an entity directly retrieved from a DataContext, such as this:

using (DemoDataContext db = new DemoDataContext()){
    var results = (from v in db.SomeTable where SqlMethods.Like(v.SomeField, "*a*a*") select v);
}


If you try to use the SqlMethods.Like() method on anything except a DataContext’s Table<T>, you’ll get the following message:

“Method ‘Boolean Like(System.String, System.String)’ cannot be used on the client; it is only for translation to SQL.”

So much for that.  I decided to write my own extension method.  I figured I could write one fairly easily using a regular expression, and I was right!  I checked out a trusty RegEx cheat sheet and found the following relevant metacharacters:

  • ^     Indicates the start of a string
  • $     Indicates the end of a string
  • *     Indicates zero or more of previous expression

Knowing this, I wrote the following extension method:

public static bool Like(this string value, string term) {
    Regex regex = new Regex(string.Format("^{0}$", term.Replace("*", ".*")), RegexOptions.IgnoreCase);
    return regex.IsMatch(value ?? string.Empty);
}


Which I can then use like this:

var results = (from v in values where v.Like("*a*a*") select v);


I can even simplify this by wrapping it up in another extension method:

public static IEnumerable<string> Like(this IEnumerable<string> source, string expression) {
    return (from s in source where s.Like(expression) select s);
}


Now all I have to do is the following:

var results = values.Like("*a*a*");


Finally, a quick usage example to prove it works:

var values = new List<string>(){
    "Widget", "Gadget", "Whatchamacallit", "Gizmo",
    "Thingamabob", "Thingamajig", "Doodad", "Doohickey"};

var results = values.Like("*a*a*");

foreach (string result in results) {
    Console.WriteLine(result);
}


Which outputs:

image

 

Hopefully you’ll find this useful!

Tags: , , ,
Posted in .NET, LINQ, SQL Server | 3 Comments »

Fixing the "Selected file was not found” Error When Adding an Attachment to an InfoPath Workflow Task Form

Posted by DevExpert on July 1st, 2009

If you’re at all familiar with creating Visual Studio-authored workflows for SharePoint, you’re probably aware that you can also create custom task forms for tasks that have been assigned in that workflow.  The task forms can either be implemented as ASP.NET forms or InfoPath forms. My personal preference is InfoPath, provided the functionality that is needed can be accomplished using InfoPath.  By choosing InfoPath, much of the overhead required to allow SharePoint to use it as a task form is already done, whereas with ASP.NET it’s up to the developer to implement.

On a recent project, I had a need to create a workflow that at a certain step, prompted the user to upload a file attachment.  InfoPath was the obvious choice because they’re simple to create, simple to deploy, and they even support attachments.  After creating the form and the workflow I tried attaching a file to the InfoPath task form, and received the following error message:

 image

I searched around a little and found that this is a known issue, and there are a few ways to fix it.  This post suggests adding the following bit of JavaScript to the WrkTaskIP.aspx page, which is responsible for hosting the InfoPath task form:

<script type="text/javascript">
    aspnetForm.encoding = "multipart/form-data";
</script>

Another approach documented here suggests modifying the application.master master page file to add the necessary enctype form tag:

<form runat="server" onsubmit="return _spFormOnSubmitWrapper();" enctype="multipart/form-data">
  ...
</form

While both of these approaches work, I wasn’t completely happy with modifying out-of-the-box SharePoint files, which isn’t recommended anyways.  I took a slightly more involved, but much more reusable approach. Any customization you make to SharePoint really should be implemented as a Feature.  I’m not going to go into the nuts and bolts of what features are, but you can learn a little more about them from this previous post.  Before I explain my approach, here are your options for accomplishing this:

  1. Modify the out-of-the-box application.master master page file on the file system.  Not recommended.
  2. Modify the out-of-the-box WrkTaskIP.aspx page on the file system.  Not recommended.
  3. Create a new task content type, create a copy of WrkTaskIP.aspx and rename it, add the JavaScript to that page, associate the new ASPX page to your new content type, then point your workflow task forms to that new content type.  Not impossible, better than the above approaches, but still a lot of unnecessary work.
  4. Create a user control with the necessary script and deploy it as a delegate control feature.  Recommend, and the approach I describe in this post.

I decided to go with JavaScript, because I knew I could insert that into a page a lot easier than I could insert a form tag attribute.  Using an approach I’ve used before on previous projects, I decided to implement this using the delegate control pattern.  Take a look here and here first for a primer on delegate controls, but basically what they allow you to do is insert custom user or server controls into a place holder in the master page using a feature.  This is perfect, because you can add functionality to all site pages immediately without actually modifying a single page.

The first step is creating the user control that will be responsible for adding the encoding to the form.  I took a little different approach here too, and used jQuery to attach the encoding element to the forms. Obviously this implies that the jQuery library is being referenced already.  There are other solutions that make this a cinch to accomplish, such as this one by the great Jan Tielens.  In fact, this solution uses the exact same approach that I’m blogging about here.  My DevExpertise.TaskFormEncoding.ascx user control looks like this:

<%@ Control Language="C#" ClassName="DevExpertiseTaskFormEncoding" %>
<script type="text/javascript" >
    $(document).ready(function() {
        $("form").each(function(i) {
            this.encoding = "multipart/form-data";
        });
    });
</script>

Now that I have the user control created, I need to create a SharePoint feature to insert this into a delegate control placeholder.  Both the default.master page and application.master pages that SharePoint use by default have a delegate control named AdditionalPageHead, which is there specifically for this purpose – to add script, CSS references, etc. to the page’s HEAD section:

<SharePoint:DelegateControl runat="server" ControlId="AdditionalPageHead" AllowMultipleControls="true"/>

The following snippet is my feature.xml file, which defines the feature.  This file is responsible for specifying the feature ID, Title, Description, etc., plus any element manifests that our feature requires:

<?xml version="1.0" encoding="utf-8" ?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/"
         Id="2D597698-5FBC-482a-BA0F-2E42DEA2E8E4"
         Title="DevExpertise InfoPath Workflow Task Form Encoding"
         Description="Adds the necessary form encoding to allow attachments 
                      to be added to InfoPath workflow task forms."
         Scope="Site"
         Version="1.0.0.0"
         ImageUrl="DevExpertise\devexpertiseLogo.png"> 
  
  <ElementManifests>
    <ElementManifest Location="elements.xml" />
  </ElementManifests>  
</Feature>

This feature is expecting an elements.xml manifest file, which is responsible for wiring up my custom user control to the AdditionalPageHead delegate control in the master page:

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Control
    Id="AdditionalPageHead"
    ControlSrc="~/_controltemplates/DevExpertise/DevExpertise.TaskFormEncoding.ascx"
    Sequence="10"/>
</Elements>

The only thing left is packaging everything up and deploying it. I always package my features up into solution packages using WSPBuilder, since a solution package can be used to deploy other feature-dependant files to SharePoint’s 12 folder structure. My entire solution folder structure looks like this:

image

Create the solution package, deploy it to SharePoint, and you will have a site collection feature ready for activation:

image

That’s it!  Now you can successfully add attachments:

image

You may be asking yourself why I went through all that trouble just to add a couple lines of JavaScript to my pages, when I could’ve just opened application.master and thrown it in there.  Well, it’s not a recommended best practice to modify system files.  If an update or service pack is installed that overwrites these files, then all your modifications are gone.  In addition, a change like that would have to be made to all web front-end servers in your farm.  This approach is extremely reusable – I can take this solution package and activate it in any site collection in any farm and I have the necessary functionality.

I’m feeling generous today and decided to include the solution package for your downloading pleasure.  As always, it comes as-is and without warranty:

Tags: , , , , ,
Posted in InfoPath, JavaScript, JQuery, SharePoint, Workflow | 2 Comments »

SharePoint Tip/Trick: Specifying a Relative Portal Site Connection Link

Posted by DevExpert on May 5th, 2009

There are a variety of reasons why you’d want to create multiple site collections – to avoid recommended capacity limits, to provide a logical site structure, etc.  One of the drawbacks with creating multiple site collections is the lack of out-of-the-box functionality to access and share content across site collections.  While portal site connections don’t do anything to access or pull content, it does allow you to specify a “connection” to another site collection, which appears in the global breadcrumb.  This makes logical navigation easier.  Consider the following example:  a company needs to have separate site collections for each department (HR, accounting, IT, etc.), but there is also a “top-level”, shared area of the environment, which will be a separate site collection.  When you’re in each of the departmental site collections, it would make sense to have a link back to the top-level site collection, to insinuate a logical hierarchy. Simply put, a portal site connection gives you a breadcrumb link to another site collection.

Let’s take a look at the above example.  I created a root site collection (http://intranet.devexpertise.com), and also an accounting site collection (http://intranet.devexpertise.com/sites/accounting). When you’re on the accounting site collection, there’s no visual indication or link back to the “root” site collection:

image

By simply adding a portal site connection, we can provide a visual indication of the logical hierarchy and link back to the root site collection.  To add a portal site connection, navigate to Site Settings > Site Collection Administration > Portal site connection, and specify a URL and a friendly name for the link:

image

Now, the breadcrumb will show a link to the root site collection:

image

Great! …as long as you’re always going to access your sites from a single URL.  What if you have multiple URLs set up, such as the situation if you allow external access to your environment and have a separate external URL (http://extranet.devexpertise.com).  The logical thing would be to just specify a relative link for the portal web address, however SharePoint won’t let you, and pops up a nice “Please enter a URL for the portal site” error:

image

Why is this really a problem?  Well, let’s say you left it as http://intranet.devexpertise.com, and accessed it from http://extranet.devexpertise.com.  The portal site connection link would still point to the intranet!

image

Lovely, huh? Fortunately, you are able to easily set this to a relative link using a few lines of code:

using (SPSite siteCollection = new SPSite("http://intranet.devexpertise.com/sites/accounting"))
{
    siteCollection.PortalUrl = "/";
}


That’s it!  Now, no matter what URL you access the accounting site from, the portal site connection link will jump you back to the correct root site collection:

image

Tags: , ,
Posted in .NET, Object Model, SharePoint | 7 Comments »

SQL Tip/Trick: Retrieving Records as a Comma-Delimited Value Using FOR XML and STUFF

Posted by DevExpert on April 14th, 2009

Once in awhile I run across a need to create a delimited list from a set of rows in a SQL table.  The old-school method is to use a cursor to iterate over these rows and build a dynamic string.  As we all know, cursors are expensive and should be avoided whenever possible.  I recently found a better way to accomplish this and wanted to share it in case you’ve run into this before.

For this example, I’m going to be working with a simple Cities table that contains a City field and a State field.  A simple SELECT statement yields the following result:

select * from Cities where State = 'New York'

image


The first step is to transform this result into a chunk of XML, and for that the FOR XML statement is perfect.  Consider the following SQL:

declare @xml varchar(1000)
set @xml = (select City from Cities where State = 'New York' for xml path(''))


This returns the following (I trimmed it down a little to fit on the page, but it does return all rows):

<City>New York City</City><City>Buffalo</City><City>Rochester</City>

Now that we have an XML string, we can just use the built-in REPLACE functions to remove the XML nodes:

set @xml = replace(@xml, '<City>', ',')
set @xml = replace(@xml, '</City>','')


This returns the following:

,New York City,Buffalo,Rochester,Yonkers,Syracuse

Now, the only thing left is to remove the beginning space and comma from this for which the new SQL 2008 STUFF function is perfect:

select stuff(@xml,1,1,'')


This returns the following, which is exactly what we need:

New York City,Buffalo,Rochester,Yonkers,Syracuse

Now, chances are you don’t want to have to declare variables and do all this in multiple operations.  This can all be wrapped into a single select statement, which makes it easy to implement:

select stuff((replace(replace(
       (select City from Cities where State = 'New York' for xml path('')), '<City>', ','
       ), '</City>','')),1,1,'')

 

That’s it!  Pretty slick, huh?

Tags: ,
Posted in SQL Server, T-SQL | 2 Comments »