May 26, 2016

DevExpress resources - Part 1: Missing images in SharePoint site


   
Missing expand ‘+’ icon in DevExpress Grid View, with a "ASPxClientGridView is undefined" JS error.

All the assemblies & web.config changes are in place according to DevExpress documentation (here)

 



Lets Double Check:
So I gathered all possible steps below from the most relevant to the least relevant from DevExpress help & forum sites:

https://www.devexpress.com/Support/Center/Question/Details/B195818
https://www.devexpress.com/Support/Center/Question/Details/Q143607 https://documentation.devexpress.com/#AspNet/CustomDocument7540

 

a.      Recheck the installation for DevExpress dlls & handlers in web.config (see here)
b.     Make sure you install ‘DevExpress.Web.vxx.y.dll’ to GAC
c.     Check that all required assemblies including 'DevExpress.Web' & 'ASPxThemes’ dlls should be copied are in Bin folder
d.     Make sure no double registration for ASPxHttpHandlerModule in web.config
e.      Make sure 'WebResource.axd' & '*.axd' keys are properly added under .NET 2.0 configuration: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\web.config:

      <add path="WebResource.axd" verb="GET" type="System.Web.Handlers.AssemblyResourceLoader" validate="True" />

      <add path="*.axd" verb="*" type="System.Web.HttpNotFoundHandler" validate="True" />

f.      Check that IIS, a net monitor or antivirus tool (if any) does not block the /DXR.axd requests
g.     Modify the IIS directory properties.
      From IIS > site > right-click > properties > Service > uncheck ‘HTTP Compression’ boxes
      From IIS > site > right-click > properties > Home Directory > select .axd > Edit > uncheck ‘Verify that   file exists’ box

If you think there are more then kindly let me know so that I can edit the list above!

Now, I double checked the WFE machines, and that everything seems okay & setup as in steps above.
So what's missing?


Solution:
It appeared that DevExpress.Web.ASPxThemes dll was not added to bin folder on one of the WFE machines that was being hit sometimes by the load balancer. After copying that dll, the image works as expected.

Soon I'll publish a new post (as Part 2), talking in details about how DevExpress resources do work.



May 11, 2016

SPSite constructor Exception The Web Application Could Not be Found


Description: When calling SPSite constructor

using (SPSite site = new SPSite(UrlString))
{
....
}

 The user will get the following FileNotFoundException:  
"The Web application at {url} could not be found. Verify that you have typed the URL correctly."
 
Given that the calling user is NOT a site collection admin or secondary admin. User has Owner read access on target site. User can access the site normally from browser.


Reason: I concluded that this is a low-level access issue. User does not have access to config db.


If you care to know how it happened in details then continue reading!

Digging for the error:
Okay, so you really wanted to know the details.. lets start by having a look from the behind the scenes at the code from Microsoft.SharePoint.dll:
 
The call starts from SPSite Constructors (with or without User token) where it tries to get local farm then pass it to another internal SPSite constructor:

.method public hidebysig specialname rtspecialname instance void .ctor (string requestUrl) cil managed
        {
                // Method begins at RVA 0x1e9b54
                // Code size 24 (0x18)
                .maxstack 8
                IL_0000: ldarg.0
                IL_0001: call class Microsoft.SharePoint.Administration.SPFarm Microsoft.SharePoint.Administration.SPFarm::get_Local()
                IL_0006: ldarg.1
                IL_0007: newobj instance void [System]System.Uri::.ctor(string)
                IL_000c: ldc.i4.0
                IL_000d: call class Microsoft.SharePoint.SPUserToken
Microsoft.SharePoint.SPSecurity::GetDefaultUserToken()
                IL_0012: call instance void Microsoft.SharePoint.SPSite::.ctor
(class Microsoft.SharePoint.Administration.SPFarm, class [System]System.Uri, bool,
class Microsoft.SharePoint.SPUserToken)

                IL_0017: ret
        } // end of method SPSite::.ctor



Check the highlighted lines. The SPFarm.Local will try to initialize a connection to local configuration
database (using .NET runtime security if it has permission), then return local farm of that db or null (if failed to read local config db). Internally, here is how get_Local() works:
SPConfigurationDatabase local = SPConfigurationDatabase.Local;

Since the account does not have access on config db, then SPFarm.Local returns null value. I also tested this part from a C# console using the same user account, calling SPFarm.Local returned null.

Back to SPSite constructor code. this constructor will pass the farm object to another internal instructor:

internal SPSite(SPFarm farm, Uri requestUri, bool contextSite, SPUserToken userToken)
                {
                        if (farm == null)
                        {
                                throw new FileNotFoundException(SPResource.GetString("WebApplicationLookupFailed", new object[]
                                {
                                        requestUri.OriginalString
                                }));
                        }
                        if (!requestUri.IsAbsoluteUri || (requestUri.Scheme !=
Uri.UriSchemeHttp && requestUri.Scheme != Uri.UriSchemeHttps))

                        {
                                throw new FileNotFoundException(SPResource.GetString("WebApplicationLookupFailed", new object[]
                                {
                                        requestUri.OriginalString
                                }));
                        }
                        ......
                        SPWebApplication sPWebApplication = SPWebApplication.Lookup(farm, requestUri, contextSite, out sPAlternateUrl, out sPSiteLookupInfo, out this.m_LookupRequiredContext);
                        if (sPWebApplication == null)
                        {
                                throw new FileNotFoundException(SPResource.GetString("WebApplicationLookupFailed", new object[]
                                {
                                        requestUri.OriginalString
                                }));
                        }
......

                }


From highlighted lines in code above, we can see that exception can be throw in 3 cases:
#1 When Farm object is null
#2 When Site uri argument is not absolute or the scheme is not either http nor https
#3 When Web application is null (when Web Application lookup fails with Alternate Url)
   
The reason in our case is #1 I believe. Check 1st highlighted line in Orange. The SPSite constructor will pass the local farm object to the internal SPSite constructor. Since the farm object is null, it will throw FileNotFoundError exception. The error message itself will be read from  “WebApplicationLookupFailed” resource key. This error message actually comes from 'Strings.cs' file.
As a quick test I used PowerShell to display the error message:

[Microsoft.SharePoint.SPResource]::GetString("WebApplicationLookupFailed")
Output:
The Web application at |0 could not be found. Verify that you have typed the URL correctly. If the URL should be serving existing content, the system administrator may need to add a new request URL mapping to the intended application.


The Lesson to be learned:

The user got a WebApplication no found exception, while the real exception is Access Denied in config db. Do not trust all exceptions to be straight forward, as SharePoint has its own way of interpreting stuff!