Jason Specland: An Occasionally Funny Software Guy

Making it up as I go along. Always.

Category: Programming (page 1 of 2)

My New Project: The Cheapo Blog

I work for BlueMetal, and we’re a big Microsoft partner. In fact, we’ve been partner of the year for the past three years running. That means that I build a lot of stuff in the Azure cloud. I’ve come to like it a great deal. I’m amazed by how simple it is to create super-powerful infrastructure at the click of a mouse, or the deployment of an ARM template.

I was so impressed with Azure that I moved my personal WordPress blogs from Dreamhost to Azure. That… was a bit of a mistake. Not because the performance was bad. It was quite good, in fact. But the problem is that even when sharing an App Service Plan between all of my blogs, using the Azure cloud as a private person who is not a corporation can get a bit expensive. My WordPress hosting costs shot up from about $10.99/mo. to about $80. Now, I had a ridiculous deal on Dreamhost. (Crazy Domain Insane, I believe they called it.) I’m certainly getting a bit better performance, and I could trivially scale it up. But that’s a lot of cash to spend every month.

A reasonable person would say, “Dang, let me migrate my blogs right the heck back to Dreamhost!” I am not a reasonable person.

Using only Azure resources, can I create a new blogging system that has performance that’s equal to or better than my WordPress blog, while still being way, way cheaper? I bet I can. It won’t be functionally competitive with the gigantic WordPress ecosystem, but I don’t use most of the stuff in the gigantic WordPress ecosystem. I’m just a simple country blogger.

Now let’s add another degree of difficulty on to this project. At work, I have a Visual Studio Enterprise subscription, with that delicious $150/month in Azure credits at my disposal. And let me tell you, I use that stuff all the time. In fact, since I’m working on different projects with different configurations, I don’t develop on my work laptop anymore. Any time I need a new work environment, I build one from scratch by building out a new VM in the Azure cloud. Easy peasy!

The downside is that I’m used to mindlessly building infrastructure on Azure, but never having to deal with the bill. For this project, I’m going to see if I can do this entirely on my own, with only my own money, using absolutely no resources that belong to my employer, and nothing that is unlicensed in any way.

There are several challenges involved in this. The first one is most obvious: I don’t actually have a Windows PC at home! What can I say, my family went all-in on the Mac a few years ago. My instinct would be to just fire up an Azure VM with Visual Studio and RDP right into it. But that would eat up a fair amount of money that I don’t want to spend.

Fortunately, my Mac is entirely capable of writing .NET Core web services using either Visual Studio for Mac or Visual Studio Code. I fooled around with Visual Studio for Mac for a little bit and it didn’t thrill me. It’s great for Unity (which I’ve dabbled in) and Xamarin (which I haven’t). But I’m building web apps, and VS Code is extremely capable for my purposes, so I’m going to go with that.

And so begins the adventure! Wish me luck!

Project Estimation for SharePoint: A Parable

EXT. OUTSIDE THE JUNGLE, DAY

An intrepid treasure hunter and his local guide stand trepidatiously outside of a dark, mysterious, wild jungle.

Treasure Hunter: How long will it take for us to get through the jungle?
Guide: It’s hard to say. The jungle is filled with dangerous traps and difficult terrain.
Treasure Hunter: Okay, how long will it take to get two miles through the jungle?
Guide: Seriously, it’s hard to say. I don’t know what we’re going to encounter…
Treasure Hunter: Just ballpark it for me.
Guide: Okay, well I’m really not certain, so I’m going to have to assume the worst… Three days?
Treasure Hunter: Three days!? To go two miles!? What are you, incompetent or something?
Guide: Okay, if everything goes absolutely perfectly… A day, maybe? But don’t hold me to that…

CUT TO: Two days later…

EXT. INSIDE A PIT TRAP IN THE MIDDLE OF THE JUNGLE, DAY

Treasure Hunter: We’re a day over budget. I’m not paying you for this, you know.

A Dog Named ‘Cat’: What Happens When You Name a SharePoint Field ‘DisplayName’?

Sometimes I feel bad for junior front-end developers who think they have a decent handle on things, and then get thrown into the world of SharePoint. They don’t have the SharePoint Spidey-sense that tells them something simple is going to go horribly wrong.

I was called on to assist a junior developer who was tearing his hair out trying to do simple CRUD operations on list items in SharePoint in an Angular application. I’d already written a (somewhat) simplifying Angular service to deal with most of the annoying parts of the REST API, so I was baffled that he was having so much trouble with it.

So I stepped into the code with him, making sure he was calling my service correctly. He was. I began to panic. Was there a bug in my service? I stepped into the service code. Everything looked fine, and SharePoint returned the proper “201 CREATED” response. But every field except one was being set.

The name of that field was “DisplayName”.

Curious.

I proceeded to create a new Custom List called “TestThisBug.” I created a field called “DisplayName” and another field called “FooDisplayName.”

sp2013-displayname-bug-in-interface

Simple, right? Then I tried to get the fields via the REST API.

sp2013-displayname-bug-in-rest

The field did not appear. Curiouser and curiouser.

I tweeted the tweet above, and told the developer to name the field something else and be on his way. I wondered, “What if we try the same operations using the JSOM?”

So, on my SharePoint 2013 VM, I fired up a Site Collection, created my list, and wrote me some JSOM code. I wrote some code that will get that list item, select a few fields (including “DisplayName”) and just display it in a table.

sp2013-every-field-but-displayname

I got every field I asked for, except for “DisplayName” which was silently disregarded. When I tried to ask for it directly via get_item('DisplayName') I was told it wasn’t initialized, despite the fact that I’d explicitly requested it.

sp2013-uninitialized-property-jsom

I began to wonder if I would run into the same creation issue my coworker was encountering. I wrote some more JSOM code to actually create a list item with the “DisplayName” field set. And, even more strangely… It worked!

sp2013-succesfully-created-item-with-jsom

I then logged on to my Office 365 Dev Tenant to see if this is still an issue.

o365-displayname-bug-in-rest

o365-displayname-bug-with-jsom-added-item

Yup! Sure is! You can see here that I can get the field name from the list via list.get_fields(), but when I return list items, the field is not returned, despite explicitly requesting it. You can also see that the “DisplayName” field that is returned from get_fields() doesn’t have any super-secret internal name that I’m missing.

But, as before, adding a list item with that field via JSOM works just fine:

o365-displayname-bug-with-jsom-added-item

So, kids, I guess the moral of this story is pretty simple: Don’t name your fields “DisplayName.”

Here’s the bug-test JSOM code.

I’ve Seen the Future…

Well, by now every SharePoint person on Earth has seen and blogged about the #FutureOfSharePoint announcement. Most of the top SharePoint bloggers have just been sitting on all this until today, but I run in far humbler circles.

So let’s look at what I wanted, and what I got:

A Master Page that’s responsive and compatible with modern web design sensibilities. Microsoft has warned us against modifying it, lest we pay the “modification tax,” but our clients keep saying, “Responsive, responsive, responsive.” You’ve got to meet us half-way.

Office Dev PnP Tooling (or something like it) baked in to Visual Studio just as well as the Feature Framework tooling was baked in to VS 2012/2013. And while we’re on the subject, can we please have some less roundabout ways to get things done? As much as I love Vesa Juvonen and the work he and his team have done, this needs to have some real Microsoft institutional oomph behind it.

And while we’re at it, let’s have a better story for client-side, non-App/Add-in-oriented development. SharePoint 2013 is approaching the sunset and 2016 is being born, and I’ve still yet to actually write an app for a client. They don’t want to set up that infrastructure, and if they have no intention of adding untrusted stuff from the internet they shouldn’t have to.

Got it, got it, got it. I’m so psyched for the SharePoint Framework, I can barely contain myself.

Okay, this isn’t SharePoint so much, but what’s the deal with javascript Intellisense in an Angular app in Visual Studio? Eh, it won’t be much of an issue for me in the future, since after recently completing a moderately large javascript project, I now solemnly swear to use Typescript forever and ever, amen.

They explicitly showed people using the SharePoint Framework using VS Code. More modern “cool” tools, less monolithic IDEs. Nice.

Either integrate Yammer like you promised or get rid of the damn thing. I was at the SharePoint Conference in Vegas where they announced the acquisition, and the two products seem no better integrated today than they were then. SharePoint 2013 could have been the launchpad from which real Office Social Networking took off, but instead Microsoft strangled it with a garrote from the back seat of a late 70’s model sedan.

Some kind of way forward for InfoPath! Surely when it comes to something as basic to human business life as forms, there must be some happy medium between “let’s use an end-of-life’d technology that no one at Microsoft will touch with a ten foot pole” and “time to write another fat check to that javascript developer!” Sure I’m usually the javascript developer they write that fat check to, but I do have some sympathy for my clients.

Nope. Yammer and InfoPath are still dead as disco. Sorry, Tessio. It’s just business.

A device that sends an electric shock to any person who attempts to use SharePoint as a relational database back-end for a super-customized, nowhere-near-the-box, not-at-all-like-SharePoint front-end. Yes, this device would probably kill me, but my smoking corpse could serve as a warning to others…

Not only did I not get this, but the SharePoint Framework will probably encourage me to do more of that type of development. It’s probably best for my health anyway.

The Future of SharePoint

Today, at 12:30 PM my local time, Microsoft is doing a big reveal at an event they call, “The Future of SharePoint.” It’s apparently going to be something big, because the SharePoint Social Media Universe has been able to talk of nothing else for weeks now.

I’ll be anxiously watching this event today, but before I do, I thought about the things that I’d like to see in the future of SharePoint.

Crystal Ball on Ice, courtesy of https://www.flickr.com/photos/punktoad/4302556980, (CC BY 2.0)

Crystal Ball on Ice, courtesy of https://www.flickr.com/photos/punktoad/4302556980, (CC BY 2.0)

Now these are not prognostications. I know an MVP or two, but they’ve remained faithful to their NDA’s. This is just what I would like to see happen with SharePoint.

  1. A Master Page that’s responsive and compatible with modern web design sensibilities. Microsoft has warned us against modifying it, lest we pay the “modification tax,” but our clients keep saying, “Responsive, responsive, responsive.” You’ve got to meet us half-way.
  2. Office Dev PnP Tooling (or something like it) baked in to Visual Studio just as well as the Feature Framework tooling was baked in to VS 2012/2013. And while we’re on the subject, can we please have some less roundabout ways to get things done? As much as I love Vesa Juvonen and the work he and his team have done, this needs to have some real Microsoft institutional oomph behind it.
  3. And while we’re at it, let’s have a better story for client-side, non-App/Add-in-oriented development. SharePoint 2013 is approaching the sunset and 2016 is being born, and I’ve still yet to actually write an app for a client. They don’t want to set up that infrastructure, and if they have no intention of adding untrusted stuff from the internet they shouldn’t have to.
  4. Okay, this isn’t SharePoint so much, but what’s the deal with javascript Intellisense in an Angular app in Visual Studio? Eh, it won’t be much of an issue for me in the future, since after recently completing a moderately large javascript project, I now solemnly swear to use Typescript forever and ever, amen.
  5. Either integrate Yammer like you promised or get rid of the damn thing. I was at the SharePoint Conference in Vegas where they announced the acquisition, and the two products seem no better integrated today than they were then. SharePoint 2013 could have been the launchpad from which real Office Social Networking took off, but instead Microsoft strangled it with a garrote from the back seat of a late 70’s model sedan.
  6. Some kind of way forward for InfoPath! Surely when it comes to something as basic to human business life as forms, there must be some happy medium between “let’s use an end-of-life’d technology that no one at Microsoft will touch with a ten foot pole” and “time to write another fat check to that javascript developer!” Sure I’m usually the javascript developer they write that fat check to, but I do have some sympathy for my clients.
  7. A device that sends an electric shock to any person who attempts to use SharePoint as a relational database back-end for a super-customized, nowhere-near-the-box, not-at-all-like-SharePoint front-end. Yes, this device would probably kill me, but my smoking corpse could serve as a warning to others…

SharePoint Saturday, NYC

I had a total blast speaking at SharePoint Saturday this past weekend. I admit I was slightly terrified at the prospect of speaking in front of a crowd of seasoned IT professionals… I was worried I’d get something wrong and provoke the ire of the crowd. But, as it turned out, the crowd was delightful and enthusiastic.

My presentation was entitled, “Love in the Time of Javascript: Useful Patterns for Client-Side Code in SharePoint.” A friend of mine from Google said that comparing javascript to cholera was unfair to cholera…

It went well, but I experienced particular delight in a trick I pulled that worked gloriously. Everyone who’s been to these sessions knows that people kind of drift in and out of them, as they discover that the session they’re attending isn’t exactly what they’re looking for, and that another session going on at the same time might be more fulfilling. Nothing wrong with that. This ain’t the theater, but it’s still slightly distracting for presenters.

So I thought, “How long would it take someone to determine that my presentation was not for them?” I guesstimated that it’d be about twelve minutes. So, before the presentation began, I wrote “9:12” on one of my business cards, and handed it out to a gentleman in the front row.

I began my presentation, and, lo and behold, someone starts making his way out. I glance at the clock on my presenter computer. 9:12 exactly! I say to the man in the front row, “Sir, what time does it say on that card I gave you?”

“9:12.”

“What time is it now?”

“9:12.”

“9:12! First walkout! I called it!”

I swear upon my very life that I didn’t pre-arrange it with the guy who left.

Oh yeah, I spoke a bit about SharePoint and javascript, too. But clearly, pulling off a magic trick was the highlight of my SharePoint Saturday.

For those who are interested, here is the PowerPoint presentation for Love in the Time of Javascript: Useful Patterns for Client-Side Code in SharePoint.

More SharePoint Annoyances: User Field Defined in XML Not Appearing in ListData.svc REST/Odata Output

Here’s another one my improv peeps can ignore.

So here’s the deal: My company has declared that they’re going to be moving our SharePoint installation to Office 365 some time in the not-too-distant future. There go my farm solutions. Add to that the fact that SharePoint 2013 is deprecating the sandbox and the writing on the wall says I’d better learn JavaScript ASAP.

So I work on a sandbox solution (since I’m still on 2010) to deploy some lists, with an included web part that uses JavaScript to query ListData.svc (and do neat stuff with the interface using knockout).

I have a User field in one of the lists called “Owner.” However, when I query ListData.svc, it doesn’t appear. (No, it’s not deferred. It’s just not there. The OwnerId field isn’t there, either.)  I bang my head against the wall a bit.  Then I add another User field to my site columns, content type, and list in Visual Studio.  Still no dice.

Then I think to add a field using the plain-old web interface.  Suddenly it works.  Could I have been defining my User columns incorrectly all this time?

[sourcecode language=”xml”]

[/sourcecode]

(I changed the name of the column, in case “Owner” was a reserved word in OData or something. Don’t judge! I was desperate!)

Apparently, all this time I’d been missing the List=”UserInfo” parameter in my list definitions. And the only… ONLY symptom I’ve ever seen from this is that the field doesn’t appear when queried via the REST interface.

Once again, SharePoint has driven me to distraction (and blog posting).

Exporting XSLTListView Web Parts to Other Webs + In Place Records Management Enabled = Null Reference Exception

Here’s the scenario: In SharePoint, you want to view one or more lists from one web in a site collection in a different web on the same site collection. What do you do? That’s easy: You go to SharePoint Designer, go to the original list view, export the XSLTListView web part that represents that view, load it into your other web and place it in whatever web part page you’d like. Boom. Dashboard.

Unless, of course, you’ve got the In Place Records Management feature enabled. In that case, you’re screwed. Everything will look fine for a while. But eventually, all of the views of your original list will fail. You will see the dreaded:


Server Error in '/' Application.
________________________________________
Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[NullReferenceException: Object reference not set to an instance of an object.]
Microsoft.Office.RecordsManagement.RecordsRepository.Records.GetCachedAllowManualRecordDeclarationSetting(CachedList list, Hashtable siteProperties) +3
Microsoft.Office.RecordsManagement.Controls.<>c__DisplayClass1.b__0() +164
Microsoft.Office.Server.Utilities.MonitoredScopeWrapper.RunWithMonitoredScope(Action code) +39
Microsoft.Office.RecordsManagement.Controls.DeclareRecordAction.GetDeclareRecordInfo() +158
Microsoft.Office.RecordsManagement.Controls.InPlaceRecordsRibbon.Page_PreRenderComplete(Object sender, EventArgs e) +74
System.EventHandler.Invoke(Object sender, EventArgs e) +0
System.Web.UI.Page.OnPreRenderComplete(EventArgs e) +11058669
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3671

Why, SharePoint!? WHY!? (Seriously, if I had a nickel for every time I shouted that…)

Well, with the help of our good friend .NET Reflector, let’s take a closer look at that stack trace, shall we?

Microsoft.Office.RecordsManagement lives in Microsoft.Office.Policy.dll. I open it up and take a look at GetCachedAllowManualRecordDeclarationSetting(CachedList list, Hashtable siteProperties). Not much there…

[sourcecode language=”csharp”]
internal static bool GetCachedAllowManualRecordDeclarationSetting(CachedList list, Hashtable siteProperties)
{
if (list.RecordsUseListSetting)
{
return list.RecordsAllowManualDeclareSetting;
}
return GetCachedAllowManualDeclarationSiteSetting(siteProperties);
}
[/sourcecode]

Nothing that’s going to throw a NullReferenceException unless the cached list itself is null. So let’s travel up the stack a bit to Microsoft.Office.RecordsManagement.Controls.<>c__DisplayClass1.b__0().

[sourcecode language=”csharp”]
public void b__0()
{
SPList list = SPContext.Current.List;
if (list != null)
{
CachedArea rootArea = CacheManager.GetManagerForContextSite().ObjectFactory.RootArea;
CachedList cachedList = CommonUtilities.GetCachedList(SPContext.Current.Web, SPContext.Current.ListId);
if (list != null) // <- WTF!? (This comment added by me.) { this.declareRecord.iprList = Records.GetCachedAllowManualRecordDeclarationSetting(cachedList, rootArea.Properties); if (this.declareRecord.iprList) { this.declareRecord.userHasRights = Records.CachedDoesUserHavePermissionsToDeclare(list, rootArea.Properties); } } } } [/sourcecode] Ah HA! The cached list is null! The inner null check is clearly meant to check the null-ness of cachedList and not list! So, thanks to a clear, obvious bug in SharePoint, you can’t use XSLTListView Web Parts on other webs in your site collection if In Place Records Management is turned on. Unfortunately, the only solution is to turn it off.

Note: I upgraded my development SharePoint instance to the February 2012 CU. This bug still exists in assembly file version 14.0.6116.5000.

Hyper-V VM Not Starting Due to Insufficient RAM, Even Though You Have Enough? Kill googlecrashhandler.exe

So this morning I start up my computer, and start up my SharePoint Development VM. I get a message saying that my VM won’t start. It says “Unable to allocate 6144 MB of RAM: Insufficient resources exist to complete the requested service. (0x800705AA).”

Well naturally I like to give my SharePoint VM lots of RAM, but 6144 is right around the amount that is actually free. So I lower it to 4096 MB. Task Manager tells me I have more than enough free RAM to do that. But I try to start it up… No dice. I lower it to 2048 MB. It starts all right, but running SharePoint + SQL Server + Visual Studio on 2 GB of RAM is not something I relish.

Finally, my Google-Fu was powerful enough to show me newly-posted answer on TechNet.

googlecrashhandler.exe? Really!? Well, seems silly, but anything’s worth a try. I kill the 2 processes and boom. My VM starts with 6 GB of RAM, just like always.

I’m writing this up for two reasons: Primarily, I’m putting this out there so Google can grab it and save my fellow devs from frustration. But secondarily, as a SharePoint developer, it’s not often that I have cause to direct WTF’s at a party other than Microsoft.

Hey, Google: WTF!?

Hey, SharePoint: Why Do You Screw Up My Content Type When I Deploy It Through Visual Studio?

So, we all love the way Visual Studio 2010 allows us to debug our SharePoint code with a single bounce on the F5 button, right? Isn’t it nice the way we can deploy with confidence, knowing that we debugged our code in the dev environment? Surely, our code and configurations will act exactly the same way when we deploy them with Add-SPSolution as they do when we deploy them with F5. Right?

Well then what the hell is up with this:

I’m doing something that I think is pretty typical. I’ve created a content type, descended from Document, to go into a document library, like so:

[sourcecode language=”xml”]












[/sourcecode]

And I’ve created a document library to hold documents of this content type, like so:

[sourcecode language=”xml”]







(blah blah blah)

(blah blah blah blah blah)


[/sourcecode]

So can you tell me why I see the following when I hit my F5 key?

A SharePoint List Configuration Screen

Hm, that’s odd. I called my content type “Project Document” not “Project Documents.” Project Documents is the name of the document library itself. Let’s take a closer look at that content type, shall we?

A SharePoint Content Type Configuration Screen

What the WHAT? That’s no content type, that’s a list instance! I wondered what I’d done wrong. It’s certainly not out of the question for me to screw up a SharePoint XML configuration somewhere. Hell, screwing that up is most of what I do all day. So I went to my test server, where I’d deployed a slightly different earlier version. The document library and content type appeared normal. Could there possibly be some difference in the way I deployed the project? I deployed the .wsp manually on the dev box… the very same .wsp I’d just debugged with F5.

A SharePoint List Configuration Screen, from a manually deployed project.

But that looks perfectly normal. What about the content type itself?

A SharePoint Content Type configuration Screen.

So… I guess this means I can’t trust content deployed through Visual Studio anymore. Hey, it’s not like I needed a streamlined workflow or anything.

Older posts