Pages

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!




October 8, 2015

How to know which lists uses a specific Template ID

Suppose you are in a situation where you see the following xml schema for a list item event receiver:


<Receivers ListTemplateId="16016">
<Receiver>
<Name>CustomAlertEventReceiver</Name>
<Type>ItemUpdating</Type>
<Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
<Class>CustomAlertEventReceiver.ItemEventReceiver.ItemEventReceiver</Class>
<SequenceNumber>10000</SequenceNumber>
</Receiver>
</Receivers>


How do you figure which list or lists the event receiver applies to?

Well, we can know if this Template ID is OOB from this list.

Also, we can use the browser if we want to check only one or 2 specific lists that we already know they exist. This post describes how to get the template ID of from list settings page using the 'g_wsaListtemplateId' variable.
http://sharepoint.stackexchange.com/questions/89030/2010-custom-list-template-id

But the stuff above do not really answer the question as the id '16016' is custom.. "I want to know all -if any- lists that uses this template ID across the whole farm"?


My answer: Let's write some code!
I wrote a simple console app to get a collection of list names that are based on a specific template ID, and their web url.
Make sure you run this code in a SharePoint server machine because it will access the local farm and iterate through web applications, site collections & webs.


Hope this helps someone!


public struct TemplateIDResult
    {
        private string _ListName;
        private string _WebUrl;
        public string ListName
        {get { return _ListName; } set { _ListName = value; }}
        public string WebUrl
        {get { return _WebUrl; } set { _WebUrl = value; }}
    }
class Program
    {
        static void Main(string[] args)
        {
            int TargetTemplateTypeVal = 16016;// a custom id
            List<TemplateIDResult> ResultsFound = new List<TemplateIDResult>();
            ResultsFound.AddRange(getTemplateTypeFoundInFarm(TargetTemplateTypeVal));
            if (ResultsFound.Count > 0)
            {
                Console.WriteLine("Results count: " + ResultsFound.Count.ToString());           
                foreach (TemplateIDResult result in ResultsFound)
                {
                    Console.WriteLine(string.Format("List name: '{0}' in Web: {1}" ,result.ListName, result.WebUrl));
                } 
            }
            Console.WriteLine();
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }
        private static List<TemplateIDResult> getTemplateTypeFoundInFarm(int TemplateTypeValue)
        {
            List<TemplateIDResult> result = new List<TemplateIDResult>();
            SPWebService service = SPFarm.Local.Services.GetValue<SPWebService>(string.Empty);
            SPWebApplicationCollection WebAppColl = service.WebApplications;
            foreach (SPWebApplication WA in WebAppColl)
            {
                result.AddRange(getTemplateTypeFoundInWebApp(WA, TemplateTypeValue));
            }
            return result;     
        }
        private static List<TemplateIDResult> getTemplateTypeFoundInWebApp(SPWebApplication WA, int TemplateTypeValue)
        {
            List<TemplateIDResult> result = new List<TemplateIDResult>();
            SPSiteCollection AllSiteColl = WA.Sites;           
            foreach (SPSite site in AllSiteColl)
            {
                #region Site
                SPSecurity.RunWithElevatedPrivileges(delegate
                {
                    using (SPSite s = new SPSite(site.ID))
                    {
                        try
                        {
                            SPWebCollection AllWebs = site.AllWebs;
                            foreach (SPWeb web in AllWebs)
                            {
                                #region Web
                                int TemplateTypeVal;
                                foreach (SPListTemplate template in web.ListTemplates)
                                {
                                    TemplateTypeVal = (int)(template.Type);
                                    if (TemplateTypeVal == TemplateTypeValue)
                                    {
                                        TemplateIDResult r = new TemplateIDResult();
                                        r.ListName = template.Name;
                                        r.WebUrl = web.Url;
                                        result.Add(r);
                                    }
                                }
                                web.Dispose();
                                #endregion
                            }
                        }
                        catch (Exception e){                            Console.WriteLine("Web access error inside: " + site.Url);}
                    }
                });
                #endregion
            }           
            return result;
        }
    }

March 3, 2015

Solving Junk Output During Project Build in Visual Studio 2013

Symptoms


I had this weird situation a while ago. A developer can build a project successfully and show the normal details (couple of lines) in output window. However, when I access the same machine, the same Visual Studio instance, and builds the same project then the project builds okay, but output window will display a lot of weird &  junk details, contains inconsistencies with .NET assemblies. This behavior will occur for all projects, even for empty projects coming from VS templates before any custom code added..

I tried the following actions but did not fix it:
  • Clean the build &rebuild
  • Close project & re-open
  • Restarting Visual Studio
  • log-out from machine then log back in


Cause
It appeared that something went wrong with my profile cache within Visual Studio.


Solution
The solution I found is to delete the Visual Studio cache. Not a perfect solution but it works!

Important: Please understand that deleting the cache will make you lose all of your personal settings in VS. You can export the settings first so you can have a backup before you proceed.

Steps
1. Delete the contents from the following folders:
  • C:\Users\<<Your Alias>>\AppData\Local\Microsoft\Team Foundation\5.0\Cache
  • C:\Users\<<Your Alias>>\AppData\Local\Microsoft\VisualStudio \12.0\ComponentModelCache
  • C:\Users\<<Your Alias>>\AppData\Local\Microsoft\VSCommon
2. From command prompt run the "devenv /resetuserdata" command:
  • For 64 bit: C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE
  • For 32 bit: C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE