2010-05-05

Windows SharePoint Search Access Denied

This is a re-post in order to make the solution to this error more transparent.  The problem was that our SharePoint Search service was not returning any results. I found the following event occuring in the Event Viewer.

================
Event details:
Event Source: Windows SharePoint Services 3 Search
Event Category: Gatherer 
Event ID: 2436
Description:
The start address cannot be crawled.
Context: Application 'Search index file on the search server', Catalog 'Search'
Details:
Access is denied. Verify that either the Default Content Access Account has access to this repository, or add a crawl rule to crawl this repository. If the repository being crawled is a SharePoint repository, verify that the account you are using has "Full Read" permissions on the SharePoint Web Application being crawled.   (0x80041205)
================

This stumped me for a long while until I finally took the time to dig in and do the proper research.  I found another error showing in the SharePoint log file:

================
CSTS3Accessor::GetDocFormat: Return error to caller, hr=8007007A - File:d:\office\source\search\search\gather\protocols\sts3\sts3acc.cxx Line:654
 ================

A simple Google search turned up this post by Yorick with the solution.

Thanks Yorick.

2010-03-29

IE8 Navigate in "Protected Mode"

If you spawn an IE session in your development read on…

I have an application that is posting data to a webpage from a client app using the IE.Navigate API.  The problem was that in IE8, the server never received the request.  Instead (when Visible was set to True), the window just opened and then disappeared.  I finally discovered the reason.

In the “Internet” zone, the “Enable Protected Mode” setting was checked.  An admirable security feature, it can be awfully annoying to the uninformed (as security features typically go).  Now, note that my URL is on our Local Intranet.  Regardless, by unchecking this option, the application immediately began functioning properly again.

Good luck with your IE8 testing.

2010-01-07

Excel's Extended Worksheet from Native Worksheet

The Setup
I recently had a request to create a simple way (user's perspective) to access and modify a SQL serer table directly without having to connect via the SQL Server Manager and navigating to the Database > Table > Edit.  After giving it some thought I decided to use VSTO to create an Excel interface to the three tables we needed to connect to.


This turned out to be an excellent choice.  90% of this project was simply "plumbing".  Hooking up the TableAdapter to the tables, generating a couple Get methods, an Update and a Delete method.  Finally implementing the SelectionChange event to determine when to update the record.


The hang-up came when I attempted to make use of the Ribbon Designer to provide a couple of user-interface options: one to switch from test to production systems and another to delete the selected record.  The system change was fairly simple once I learned how to export the Ribbon XML and implement the Callback method for a RibbonComboBox control:
  public void comboSystem_TextChanged(Office.IRibbonControl control, string text)
For a full list of prototypes for various Ribbon control events see the list at MSDN here.


The real problem was with the Delete routine.  With three different worksheets that could potentially have been active I needed some way to determine on which table to call the DELETE statement.  I started by creating a C# Interface by which my VSTO Worksheets must abide: ITableSheet that contained just two methods (RefreshData and DeleteRecord) and implemented them appropriately for each of the three Worksheets.  I thought that if I could access the ActiveSheet from the RibbonButton click event, then of course I could simply cast it to an ITableSheet and call DeleteRecord.  This provides an easily scalable way of adding new tables later, should that be necessary.


The Problem
Here's where I learned the difference between the native worksheet (Microsoft.Office.Interop.Excel.Worksheet) and the extended worksheet (Microsoft.Office.Tools.Excel.Worksheet).  It so happens that the ActiveSheet property is a native Worksheet object.  This is not easily cast to a VSTO (extended) Worksheet object.


And here's where the solution gets a little messy.


VSTO 2005: there's an alleged "unsupported" way to make this conversion.  That is to add a method called "GetExtendedWorksheet" to your project.  You can see a discussion on the topic here.  And you can find an example use of it here.


VSTO 2008: Unfortunately, Microsoft prevented this method by removing access to the RuntimeCallback object in VSTO 2008.  This is the version of VSTO that I was using.  A short discussion can be found here.




The Solution (for now)
The work-around that I implemented was to create an ActiveTableSheet property in my ThisWorkbook of type ITableSheet.  When a new worksheet becomes active I manually set the ActiveTableSheet.  Then during the RibbonButton click event, I can access Globals.ThisWorkbook.ActiveTableSheet.DeleteRecord.


The Real Solution (VS 2010)
The good news is that Microsoft appears to be providing a fully supported method of converting the native worksheet to an extended worksheet in VS 2010.  (This is beta and is subject to change.)

2009-11-22

Exchange Contacts Global View

In our IT organization, we use an Exchange shared mailbox to receive EDI mail and store CRM information such as phone numbers, email addresses, and other contact information.  A few very useful features of Microsoft Exchange and Outlook come together to help provide a shared contacts list for our EDI group.
1. Custom Fields
2. Custom Views
3. Categories


With folder-level custom fields, I was able to configure our EDI contacts list with an additional field to indicate the SAP partner number.  This partner number identifies the EDI transactions in our ERP system.


I then organized a view, using two new categories: Customer and Vendor and added the SAP Partner field to this view.

Finally, in the "Define Views" screen, I copied the "" view to a new view named "KEG EDI View".  It is important to choose "This folder, visible to everyone".  



This creates the view on the Exchange server and allows the view to be chosen by anyone with permission to this contact list.














2009-09-30

VS .NET Database Edition

I think the DB Professional edition of VS .NET is a great tool to help release test- and production-ready projects in a way similar to releasing SAP transports. I’m using this for a handful of applications to maintain source code control in VSS.

VS .NET Database edition lets you import the entire test database schema into a VS project and perform schema comparisons between any combination of: VS project, test db, and production db.

The general process I follow is:
1. Check out code modules required for change (may include client, web app, or db items).
2. Comment changes with issue number assigned.
3. Release to test environment (keep code checked out).
4. Have functional team test the corrections.
5. Request release to production environment.
6. Check code back into VSS and provide issue number and brief description as comment.

My solution contains both the Database project and the Web application project.


























The initial DB schema is designed in SQL server manager and imported into VS .NET Database project.


After the initial import, any alterations are done within the VS .NET UI.


I can perform a schema comparison between the code and the test db.


Results of schema comparison:


From here, you can push your database schema changes to the target database.

2009-09-27

Configuring a UDDI Registry for SAP Web Services

When designing your internal UDDI registry, planning is key.  There are a lot of posts about using UDDI but most all of them show end results too generic for immediate use.  Because it was so difficult to find a good template design from which to start, I'm writing this.


UDDI Provider Name
The UDDI specification is quite generic.  The businessEntity element (MS UDDI "Provider") can be configured to represent a user, a development team, a machine name, or something else entirely.  To quote the Microsoft UDDI Guide: "The most important aspect of choosing a provider construct is consistency."

After much contemplation and testing, I found that the most logical and useful Provider would be the root domain name of the host test server.  (Example: www-test.intra.net)  
  • In this way, multiple web services can be listed under a single Provider.
  • If the owner changes hands, it's simple to reassign the Provider to someone else.
  • When a WSDL is retrieved for development, it is initially pointing to a non-production system.  Dynamic web references make it easy to point to a production system using an easy-to-remember cross reference (in this case: remove "-test" from the domain name).
SAP NetWeaver 7.0 eHP1
There are a handful of good blogs out there describing how to create the web service definition in SAP NetWeaver, so I won't go into too much detail.  Here are the important things I learned:
  • Create your Service Definition around a function GROUP for the biggest benefit.  This gives you multiple operations per service.
  • Keep the "Deploy Service" checkbox checked to auto-generate the configuration in SOA Manager.  But this is only valid for the development system because...
  • The SOA Manager configuration is no longer transportable via CTS!  This was an eye-opener.  At first I was upset, then distraught, and finally impressed.  This is a great design, but it means you must create your SOA Manager configuration(s) for web services in each system after you transport the Service Definition.  And although not a strict requirement, I suggest that you name the service and endpoints exactly the same so that they have the same SICF path to the endpoint.  This allows the consumer to change systems with ease.
Assuming a three-system landscape (development, quality, and production), you'll find that the WSDL will be different for each system in which the SOA Manager configuration is created. (A unique GUID is assigned at the time of create.) This causes issues only with the WSDL. You can't change just the root domain name to point to the WSDL for another system; instead you need a completely new URL.

But that's okay! My suggestion: only publish the WSDL of your quality system into the UDDI registry. This still meets the requirement set forth earlier: publish the test host server. And it will also allow other (non-SAP) developers access to the WSDL. (This was useful because, in our case, these users already existed in our quality system as a copy of production. In our development system, we would have had to create all of these non-SAP users just to access WSDLs.)

Finally, here is an example of a similar document I put together for release across our IT teams. As mentioned, it is important for all web service publishers to follow the same naming convention when publishing to the UDDI registry. I believe the conventions and best practices below allow for all the search requirements as well as the flexibility in describing and documenting your web services.


Sample Naming Conventions



Field
Rules to Follow When Supplying this Value
Example
Provider
Root domain name of TEST server at which the web service resides.
www-q15s.intra.net
Service Name
Short name of service.

Service Description
Describe the business intent of the web service.

Service Categories
Assign Business Unit.
Assign Business Area.
Jasper, IN
Engineering
Binding Access Point
WSDL URL

Binding Descripiton
List of operations provided by web service.
ZERfcWsExtBackflushV2
ZERfcWsExtDiscreteBf


Sample Best Practices
  • Each publisher (user) should create a provider (server) under their own account.  If more than one publisher is publishing web services on the same server, the result will be that the server name appears multiple times in search results (once for each publisher).  That's okay.
  • All WSDLs are to be published to the UDDI from the TEST server.  Use the following cross reference for executing the web service in a production environment:

    Test Domain
    Production Domain
    www-q15s.intra.net
    www-p15s.intra.net
    www-test.intra.net
    www.intra.net
  • Do not duplicate the provider (server name) for each web service.  Instead assign multiple web services to a single provider.
  • The service contains the functional details.  Enter a human-readable description of the service into the service description.
  • The binding contains the technical details.  Enter the list of the web service operations into the binding description.
  • To keep things simple, do not reference tModels in your bindings.  In my experience, this adds a great deal of complication and little to no additional value.
Enjoy.
Jeff

2009-09-26