InfoPath - external data from SharePoint List error

I had this error "The operation could not be completed" when trying to connect to a SharePoint List as an external data connection in InfoPath today.

Show Details just says "Unable to connect to the SharePoint site."

image

Figure: The message box really doesn't tell you anything.

Turned out, I was testing with a new managed path on http://server/sites/TravelFunds/  But the web application did not have a site at the root path.  So the quick fix was to create a new team site (blank site might work too) at the root path http://server/ and then come back to InfoPath, and http://server/sites/TravelFunds/ will now work as expected.

 

This was one of many posts that I read regarding similar problems, and the one that actually applied to me.  http://vspug.com/ssa/2010/03/15/infopath-2010-cannot-connect-to-sharepoint-2010/

Silverlight + SharePoint 2010 - did you just deploy customizations to SharePoint via the document upload?

Just finished my presentation earlier tonight in SDDN regarding Silverlight and SharePoint.  I had some initial reservations whether true Silverlight people want to even know about SharePoint, but I was pretty blown away by their feedback, interesting questions, and I think they found the session insightful. 

This is good :-)

 

I think I delivered my first "shock and awe" when people first saw me deploy to SharePoint.  I finished building my XAP file, and then browsed over to SharePoint, selected my Shared Documents library, clicked upload files (and for additional effect, used the drag & drop upload facility in SharePoint 2010).  Before you knew it, I had the XAP file in my document library, and I'm adding a Silverlight web part and configuring the XAP URL.

For comedy effect, I was pretending as if this is business as usual.

You guys were too good and picked it up right away - it was just too magical.  Hold on a second!  Did you just by-passed all the system admins and deployed customization code to your SharePoint server

The absolutely correct answer is, no, not really, I just deployed customizations to the SharePoint UI, an additional tool if you will, that will help you do your job easier.  Technically, it is not running on the server.  Technically, you can run a separate .NET exe tool to work against SharePoint via the same web services and it can do similar things.

Depending who you are, this might be too magical, and thus, way too dangerous.  I think the thought falls into two categories, and I'm hoping by discussing this, we can compare some thoughts on the PROs and CONs of deploying Silverlight to SharePoint.

 

PRO

  • Bypass system admins
  • Can rapidly develop and test.  Can rapidly update new version
  • Can create simple tools and install them on SharePoint quickly
  • Deploy to SharePoint online

CON

  • Unsafe code, is still unsafe
  • I can deploy a Silverlight webpart that will take my boss' permissions and copy sensitive data to a public location

 

I suggest a compromised workaround for Production SharePoint

  • Block upload of *.XAP files from Central Administration | Web Applications
  • Allow sandbox solutions - which can install XAP files, via the Solutions Gallery
  • Rely only on in-house developed solutions, or solutions purchased through a trusted and verified source such as Office.com, Bamboo, or ProdUShare.

 

At the end of the day, I believe that yes - tools can be used for evil, but for many many businesses, the need for tools to help them to be more efficient, and the need for a stable server that doesn't die all the time, far out-weights the risks of allowing Silverlight solutions.

  • A badly behaving Silverlight crashes one browser, affecting one user
  • A badly behaving web page customization crashes the App Pool, and affects many users

In terms of customizing SharePoint to rapidly meet business needs and still maintain high levels of server availability, you can't ignore or brush off Silverlight + SharePoint possibilities.

I hope the market will agree with me, and I think as long as you don't use your tools for evil, you can help a lot of people with what you can build.

 

I'm still so excited.

VB.NET - there are times when you have to keep an open mind

I suddenly found myself needing to write a very simple upload method in our MVC controller.  The uploaded file is in CSV format.

The question that immediately jumps to mind is, where do I find a CSV parser?

  • Do I write my own - it may sound simple, but as soon as you start to think about all the various permutations of splitting a line of text, with all the escape characters as well as error handling, actually, it is NOT simple at all
    1. How do you handle the case where the user actually wants to use comma (,) in a field
    2. Do you include or exclude header row
    3. How do you handle line numbers and parse error
    4. What do you do with extra spaces or tabs
    5. How do you handle line breaks
    6. What about lines that didn't have matching number of fields
  • Do I then, just re-use someone else's example
  • Or do I use the one that's supplied and supported by Microsoft, and already installed on your machine as part of the .NET Framework since .NET 2.0?

The answer is blindingly obvious - use Microsoft's one - move on, next problem.

  • Well, it's in Microsoft.VisualBasic.FileIO

Hmm, let me think about this again…

 

This is where I find many C# developers suffer, we would rather build our own untested, unsupported code to do CSV parsing, either with String.Split(',') or with clever Regex.  We're convinced that our own code is better somehow than the Microsoft supplied library.  We're so convinced, we'll run off and spend 30minutes building our own parser, we'll follow by spending 2 hours on testing our parser and making sure it's bulletproof.

So I took a good look at myself and stopped.  I said to myself. 

No, I'll be pragmatic.

 

The Microsoft VB.NET CSV parser is part of the TextFieldParser class.  Documented here:

http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.fileio.textfieldparser.aspx

 

Through the Common Language Runtime (CLR) we can include Microsoft.VisualBasic library easily in our C# project.  Here they are, happily (may be) next to each other, and doing work for me.

image

 

The actual code is extremely simple:

using (TextFieldParser reader = new TextFieldParser(fileUpload.InputStream))
{
    reader.TextFieldType = FieldType.Delimited;
    reader.Delimiters = new[] { "," };

    while (!reader.EndOfData)
    {
        string[] parts = reader.ReadFields();

        if (parts.Length != 5)
        {
            // problem.
            continue;
        }
        string customerCode = parts[0];
        string customerName = parts[1];
        string contact = parts[2];
        string phone = parts[3];
        string information = parts[4];

        var customer = customers.FirstOrDefault(c => c.CustomerCode == customerCode);
        if (customer == null)
        {
            // new
            customer = new Customer()
            {
                CustomerCode = customerCode,
            };
            Entities.Customers.AddObject(customer);
        }

        customer.CustomerName = customerName;
        customer.CustomerPhone = phone;
        customer.CustomerContact = contact;
        customer.Information = information;
    }
    Entities.SaveChanges();
}

TIP - Silverlight - InitParams and ApplicationLifeTimeService(s)

I have this love-hate relationship with InitParams

Like

  • Pre-download values to Silverlight, so it's available to the client before Silverlight even starts rendering
  • Don't have to worry about whether Silverlight can talk to any data source - if you can't see the webpage then the problem is elsewhere

Dislike

  • Well it's on the web page…  anyone could see it, and probably tweak it via DOM manipulation
  • If you bind to this data, you can't really "update" it if the data changes on the server.  If say the user settings has changed, you'll need a F5 refresh to force the Silverlight client to reload.  In a sense this is often treated like read-only data.

One thing we can fix

  • A really large App.Current with lots of different values sucked out from the initParams during App_Start

 

Using ApplicationLifeTimeServices

1. Write a Lifetime Service

    public class CompanyApplicationLifeTimeService : IApplicationService
    {
        static CompanyApplicationLifeTimeService _current = null;

        public static CompanyApplicationLifeTimeService Current
        {
            get
            {
                return _current;
            }
        }

        #region IApplicationService Members

        public void StartService(ApplicationServiceContext context)
        {            
            _current = this;
            var parseThisStuff = context.ApplicationInitParams;
        }

        public void StopService()
        {
            _current = null;
        }

        #endregion
    }

2. Add this to your App.Xaml

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
             x:Class="DispatchKing.Silverlight.App"
             xmlns:common="clr-namespace:DispatchKing.Silverlight.Common"
             >
  <Application.ApplicationLifetimeObjects>
    <common:CompanyApplicationLifeTimeService x:Name="CompanyLifeTimeService" />
  </Application.ApplicationLifetimeObjects>
  <Application.Resources>
    <ResourceDictionary>
   ...

 

3. Now anywhere in your code you have access to the service Singleton

CompanyApplicationlifeTimeService.Current.GiveMeStuff

Silverlight - sharing a common class between Silverlight and .NET

Because Silverlight is compiled against a separate set of Silverlight runtime, we can not reference or share a common library between a Silverlight project and a normal .NET project.

One very common and simple workaround is then to create a common project for .NET, and a common project for Silverlight, and then add the files as existing links from the .NET project to the Silverlight project.  This ensures that the same files are shared by the two sides and we have our matching class definitions.

 

With RIA, there is a new way.

image

In the .NET project, name your extra files with xxx.shared.cs

Compile your .NET project.  This triggers the RIA toolkit to run and generate some files for us:

image

 

So you no longer need to share a file via external link.