Posted by Mark Baylor on 2/23/2009 8:25 PM

This may very well be the understatement of the century.

SharePoint is not only hard to style, but it is so far from semantically correct markup and accessible code that it blows my mind.  It has become less difficult to blow my mind these days.

I opened up the core.css file, which is the stylesheet that drives all of the SharePoint sites out of the box, and it is a gigantic 4,500 lines of CSS.  That is incredible.  To make matters worse, there isn’t a lick of inheritance.  Among several other things, the same exact font family is declared a lot.  Also, the core.css is declared last on the page, so forget about overriding the css that is already there.

Of course, people have found workarounds for much of these shenanigans.  An article by Cameron Moll has great insight and also links to other great resources.

No wonder so many companies are using the out of the box styles.  I am going to try and tackle this beast.  Wish me luck and I will be sure to post my findings here.

Comments (5)
Tags: , | Categories: Accessibility, Code, Setup
Posted by Mark Baylor on 2/19/2009 7:39 PM

How’s that title for alliteration?

SharePoint Server 2007 does NOT automatically enable search for you. It’s as simple as that, so we need to do it.

  1. You need to go into Central Administrator first. This is where you maintain pretty much everything within your server farm.
  2. Click on Operations.
  3. Under Topology and Services, click on Services on Server.
  4. Make sure the Office SharePoint Server Search Service is enabled. If it is disabled, click Start.
  5. Enter your Shared Services Administration
  6. Under Search, click on Search settings
  7. If there are items in the index, and your search still doesn’t work, there may be other issues, like the Indexing Service for your server may not be started.
  8. Click on Content sources and crawl schedules
  9. There should be a Content Source already created: click on the name of that Content Source.
  10. Under Crawl Schedules, setup schedules for Full and Incremental Crawl
  11. Under Start Full Crawl, check Start full crawl of this content source
  12. Click OK

Now your content should be crawled. You will also be amazed to find that .pdf is not a default crawl type.

  1. Go back under Crawl Settings
  2. Click on File types and add the pdf extension

Phew, now we should have a semi functional search service. Keep in mind that there are many other settings that can be set. Nose around and setup the other sections of the search service.

Comments (2)
Tags: , | Categories: Setup
Posted by Mark Baylor on 2/19/2009 12:42 AM

Sometimes no matter how hard you search you can’t find a viable solution for a problem. After almost giving up and using the infamous IFRAME, I finally found a good solution so users can save a generated PDF by the correct filename.

History

I built an invoicing application to provide downloadable invoices for our dealer base, and security is of the utmost importance because of the sensitivity of financial data. We needed to find a solution for displaying invoices to said dealers, and make sure it was easy for them to print and save the data.

What we have now for an invoicing system

We decided to go for the downloadable PDF after several other more seemingly viable attempts failed. We tried using Crystal Reports to generate invoices on the fly, but to no avail as the views that have been written run very slowly. We also tried just harvesting data and creating an ASP.NET page to display the data straight on the page without any additional tools. The invoicing data became overly complicated and there were far too many gotchas with business rules to go that route. Rewriting the business rules was just not an option in the timeframe that we were given.

Where we eventually want the invoicing system to go

In the future when we are not moving 100 MPH all the time, there are several options that would make more sense. Datamarts would work great as the data would be optimized for quicker viewing and we can mold the data in any way we would like. We could then throw a Microsoft SQL Reporting Services front end on the data and use it on the web. This would require someone to deeply understand the data and rewrite a report, but it would provide for a better experience online.

Decision on a technology to provide PDFs

We ultimately decided to generate PDFs daily and keep them on a separate server. This offload would:

  • help keep bloat down on the frontend server as we will have thousands of PDF invoices
  • allow for a strong security model. With sensitive financial documents we could not have the files within the web root. By keeping them separate we could use a few .NET technologies to check security and go and grab the file
  • allow for quick file load. All of the slow processing work would be done ahead of time so the dealer would not feel the pain

Initial technologies I tried for PDF handling

I really thought this was going to be easy, so I quickly dove into coding.

Take 1

I decided I would use the Server.TransferFile method in .NET. It would give me control of the response object, and would give me the security I needed as I could use code to check if a dealer had permissions, and then go and get the file using a UNC.  It all worked out great.  I was actually loading it into a modal popup box and the functionality was perfect…until I tried to save the document.  It always came back with the same filename: “pdf.pdf”  That wasn’t going to work as dealers were going to be saving a lot of these invoices.  That would mean having to type in the invoice number manually.  I knew we would have a barrage of complaints right when we launched.

When you display the file inline, the file takes on the “pdf.pdf” filename.  When you use the attachment functionality in the response header it will work as expected.  You can save the file or open the file with the correct filename.

Take 2

I had remembered how an old CMS system I was using called Ektron was using an IFRAME to display files.  There was a save button in the main page, and the file would load in the IFRAME.  I scratched my head when I saw this functionality.  I was irritated at the way it functioned because I hadn’t seem an IFRAME in ages.

Turns out I had to resort to this at first.  By doing this, you can set the frame to load the file with a content header of inline, but also provide a button that uses the content header of attachment.  In this way there was an alternate way of saving the file, as to not irritate dealers.

I couldn’t sleep at night using this technology.  It seemed so 90s.  I thought to myself that I would go with this unless another solution presented itself.

Final technology I went with for PDF handling

Luckily a solution did present itself: the HttpHandler.  ASP.NET has an ashx extension that does not inherit all of the classes that a standard aspx page does.  This means faster speed, and I could make some modifications to the web.config to handle files in a more intelligent way.

I was able to use a wildcard *.ashx in the web.config.  Whenever there was a request for <invoiceNumber>.ashx, I was able to go to the handler, use the value in the wildcard, and pull back the invoice.  The beauty of this is that when you save the file, it uses the page name as the filename.  This filename uses the invoice number that is passed in.

Voila, a usable solution.

Conclusion

Although not the most world class system, I find that actually using world class solutions seems far and few between.  Every infrastructure is different, and in this case this was the best, most efficient solution.  PDFs come up very quickly, a security model is in place, and the whole system has a peppy feel to it.

Comments (22)
Tags: | Categories: Code

About baylorstudios.

baylorstudios is a small web design studio based in West Bend, WI with Mark Baylor at the wheel.  This blog focuses on the trials and tribulations of being a web developer and the problems that must be overcome to create a website.