SP2010 Branding Tip Series

Randy Drisgill:

ILSpy–nová alternativa k již placenému RedGate .NET Reflector

Společnost RedGate se bohužel rozhodla zpoplatnit asi nejznámější produkt mezi .NET vývojáři, a to produktu .NET Reflector (http://www.reflector.net/).

Tento produkt měl sice spoustu much, ale hodně krát nám pomohl objasnit chování některých nedeterministických funkcí a knihoven, zejména v SharePointu. To co mě mrzí nejvíce není ani samotné zpoplatnění (v celku zanedbatelných 35 USD), ale to že RedGate na tom od převzetí od vývojáře Lutz Roedera  v roce 2008 neudělal vůbec nic! Tedy integraci do menu Visual Studia nepovažuji za pokrok.

    

Naštěstí se objevila další open source alternativa jménem ILSpy: http://wiki.sharpdevelop.net/ilspy.ashx

image

 

Která je až nápadně podobná .NET Reflectoru, takže přechod není tak bolestný Obličej s očima v sloup 

Samotný ILSpy je ale založený na UI WPF, .NET Reflector stále využívá Windows Forms. To ale samozřejmě není z pohledu funkčnosti důležité, hlavní jsou skutečné features:

ILSpy Features

  • Assembly browsing
  • IL Disassembly
  • Decompilation to C#
    • Supports lambdas and ‚yield return‘
  • Saving of resources
  • Search for types/methods/properties (substring)
  • Hyperlink-based type/method/property navigation
  • Base/Derived types navigation
  • Navigation history
  • BAML to XAML decompiler
  • Save Assembly as C# Project
  • Find usage of field/method
  • Extensibile via plugins (MEF)

 

ILSpy Roadmap

  • Improve the decompiler
    • Add support for object initializers
  • Assembly Lists
  • Improve search performance
  • Debugger
  • Bookmarks
  • Find usage of type/property/event

 

Stránka projektu: http://wiki.sharpdevelop.net/ilspy.ashx

Twitter: http://twitter.com/ilspy

SQL Server: zobrazení počtu řádků, sloupců, velikosti tabulek v KB přes všechny tabulky v databázi

Úžasný script pro zobrazení přehledných statistický informací o databázi, zejména pokud hledáte největší tabulky v neznámé struktuře databáze:

image

[more]

USE DatabaseName 
GO 
CREATE TABLE #temp ( 
table_name sysname , 
row_count INT, 
reserved_size VARCHAR(50), 
data_size VARCHAR(50), 
index_size VARCHAR(50), 
unused_size VARCHAR(50)) 
SET NOCOUNT ON 
INSERT #temp 
EXEC sp_msforeachtable 'sp_spaceused ''?''' 
SELECT a.table_name, 
a.row_count, 
COUNT(*) AS col_count, 
a.data_size 
FROM #temp a 
INNER JOIN information_schema.columns b 
ON a.table_name collate database_default 
= b.table_name collate database_default 
GROUP BY a.table_name, a.row_count, a.data_size 
ORDER BY CAST(REPLACE(a.data_size, ' KB', '') AS integer) DESC 
DROP TABLE #temp

 

Zdroj:

http://blog.sqlauthority.com/2007/01/10/sql-server-query-to-find-number-rows-columns-bytesize-for-each-table-in-the-current-database-find-biggest-table-in-database/

Nelze modifikovat nastavení IIS WAMREG admin Service – nastavení DCOM je zašednuté/disabled na Windows Server 2008 R2

Problém je v tom, že aktuálně přihlášený uživatel nemá přístup k danému klíči v registrech systému.

Konkrétně jde o klíč v registrech:

HKEY_CLASSES_ROOT\AppID\{61738644-F196-11D0-9953-00C04FD919C1}

Aby jste tedy mohli změnit nastavení konkrétního DCOM objektu, je potřeba provést změnu nastavení v registrech a tento klíč přiřadit vlastníkům ze skupiny Administrators.

Pokud nyní zavřete správu DCOM objektů a znovu otevřete, již bude možné modifikovat nastavení IIS WAMREG admin Service DCOM objektu.

MS CRM 2011: Instalace BIDS Extensions – Another version of this product is already installed

Tento problém nastane pouze pokud je nainstalována již dřívější verze souboru “mui-i386.msi”, která je součástí CRM 2011 Outlook klienta. Aby bylo možné aplikaci BIDS Extensions nainstalovat, je potřeba provést tyto akce:

  1. Stáhnout a rozbalit soubor CRM2011-i386-MUI
  2. Stáhnout a spustit balíček CRM2011-BIDSExtensions, po spuštění vznikne na rootu disku na kterém je tento balíček stažený nová složka s názvem ve tvaru GUID, tuto složku celou zkopírujte do jiného umístění (například C:\BIDS_EXT) a ukončete instalátor
  3. V této složce (C:\BIDS_EXT) nahraďte všechny soubory rozbalené z CRM2011-i386-MUI, přepište hlavně soubor muisetup_i386.msi
  4. Hotovo, nyní instalátor setupbidsextensions.exe proběhne bez problémů.

SharePoint Search Crawler indexuje na publishing portálu kompletně celou stránku–jak indexovat pouze obsah bez navigace a ostatních rušivých elementů

Search Crawler na publishing portálu indexuje vždy kompletní stránku, tak jak dostane HTML, tak ho uloží do své databáze. To je ovšem problém, neboť následně při vyhledávání vyhledává texty i v navigaci webu nebo hlavičce a patičce. Tyto elementy jsou ale ve většině případů pro všechny stránky na portále stejné, uživatel tak dostává nerelevantní výsledky (navíc stále stejné):

image

Neexistuje možnost, jak automaticky donutit Search Server, aby toto chování změnil a například ignoroval stále stejné elementy na stránce, případně jinak pomocí tagu vynechával zvolené oblasti v master page.

Udělal jsem si proto malého pomocníka, který se vloží do masterpage v podobě:

[more]

<DevIT:SearchCrawlTrimmedControl runat="server" SearchAccount="MySearchAccount">

zde vlozte menu, header, footer... vse co chcete skryt pred indexerem

</DevIT:SearchCrawlTrimmedControl>

Kde uvnitř ovládacího prvku SearchCrawlTrimmedControl jsou všechny elementy, které chci skrýt před indexerem obsahu. Tato třída pak následně podle přistupujícího účtu skryje nebo zobrazí vybrané elementy.

/// <summary> 
/// Ovladaci prvek pro skyti vsech nepotrebnych veci v masterpage pri indexovani - aby se indexoval pouze samotny obsah stranky 
/// <DevIT:SearchCrawlTrimmedControl runat="server">  
/// <!-- zde vlozte menu, header, footer... vse co chcete skryt pred indexerem --> 
/// </DevIT:SearchCrawlTrimmedControl> 
/// </summary> 
public class SearchCrawlTrimmedControl : Control 
{ 
    public string SearchAccount 
    { 
        get { 
            string ret = ViewState["SearchAccount"] as string; 
            if (string.IsNullOrEmpty(ret)) 
                return "spsearch"; 
            return ret; 
        } 
        set { ViewState["SearchAccount"] = value; } 
    }

    protected override void Render(HtmlTextWriter writer) 
    { 
        bool render = true; 
        SPUser cu = SPContext.Current.Web.CurrentUser; 
        if (cu != null) 
        { 
            if (cu.LoginName.ToLower().EndsWith(SearchAccount)) 
            { 
                render = false; 
            } 
        } 
        if (Context.Request != null && Context.Request.UserAgent != null && 
            Context.Request.UserAgent.ToLower().Contains("robot")) 
        { 
            render = false; 
        } 
        if (render) 
        { 
            base.Render(writer); 
        } 
        else 
        { 
        } 
    } 
}

An error occurred during the processing of /_catalogs/masterpage/MyCustom.master. Code blocks are not allowed in this file.

Vložení server side kódu přímo do masterpage nebo do stránek předlohy je nutné povolit vložením následující direktivy do souboru web.config:

[more]

 <SharePoint>
   <SafeMode MaxControls=“200″ CallStack=“false“ DirectFileDependencies=“10″ TotalFileDependencies=“50″ AllowPageLevelTrace=“false“>
     <PageParserPaths>
           
<PageParserPath VirtualPath=“~/*“ CompilationMode=“Always“ AllowServerSideScript=“true“ />
     </PageParserPaths>
   </SafeMode>

Kde VirtualPath může být cesta do knihovny stránek předlohy, nebo v mém případě je možné tuto akci povolit pro celou webovou aplikaci.

SharePoint 2010 + Linq + anonymní uživatel

Při vytváření webové aplikace na SharePoint 2010 s anonymní přístupem jsem narazil jednu z mnoha nedokumentovaných vlastností SharePointu 2010, kdy po zapnutí anonymního přístupu přestal fungovat LINQ a začaly vznikat chyby při snaze přistupovat k seznamům právě pomocí těchto dotazů.

První pokus byl samozřejmě obalit tuto funkci zobrazující navigaci eskalací oprávnění na systémového uživatele pomocí funkce SPSecurity.RunWithElevatedPrivileges, to ale nikam nevedlo a Linq nepřevzal oprávnění.

image

Nebyl jsem samozřejmě první kdo na to narazil, našel jsem jeden post, který to řeší:

[more]

http://jcapka.blogspot.com/2010/05/making-linq-to-sharepoint-work-for.html

Takto:

public static class AnonymousContextSwitch 
    {  
        public static void RunWithElevatedPrivelligesAndContextSwitch( 
                SPSecurity.CodeToRunElevated secureCode) 
        { 
            try 
            { 
                //If there is a SPContext.Current object and there is no known user, 
                // we need to take action 
                bool nullUser = (SPContext.Current != null && 
                       SPContext.Current.Web.CurrentUser == null);

                HttpContext backupCtx = HttpContext.Current; 
                if (nullUser) 
                    HttpContext.Current = null;

                SPSecurity.RunWithElevatedPrivileges(secureCode); 
                if (nullUser) 
                    HttpContext.Current = backupCtx; 
            } 
            catch (Exception ex) 
            { 
                string errorMessage = "Error running code in null http context"; 
                //Use your favourite form of logging to log the error message and exception .... 
            } 
        } 
    }

Toto řešení sice funguje, je ale potřeba si rozhodnout, zda je to na aktuálním projektu bezpečné a co přesně pod tímto oprávněním anonymní uživatel může provádět, pokud pouze číst informace (kde nejsou důvěrné informace řešeny formou oprávnění), tak je to možná pro některé případy použitelné. Lepší způsob ale je buď vůbec LINQ nepoužít (což už u hotového projektu lze jen obtížně), nebo vytvořit nového uživatele v SP s omezeným oprávněním a předávat jeho kontext při inicializaci objektu SPSite, tedy mírně zmodifikovat výše uvedenou třídu AnonymousContextSwitch tak, aby se kontext vytvořil pro tohoto uživatele s nízkým oprávněním.

SharePoint: This page contains content or formatting that is not valid. You can find more information in the affected sections

Tuto pěknou chybu způsobují validátory použité ve vlastní webpartě, chyba vzniká pouze pokud se jedná o stránku pro publikování (publishing page).

SharePoint z neznámého důvodu spustí validace na webpartě při ukládání stránky a nedovolí stránku uložit pokud validace ovládacích prvků neprojde v pořádku. Na tom by nebylo nic divného pokud není specifikovaný atribut ValidationGroup a měla by se kontrolovat logicky celá stránka, ale SharePoint kontroluje validaci i na ovládacích prvcích kde je ValidationGroup specifikovaný.

Na lepší způsob než níže uvedený jsem zatím nepřišel, kdy vypínám validace v případě, že aktuální stránka je v editačním módu:

protected override void CreateChildControls()
{

     // some code

     if (SPContext.Current.FormContext.FormMode == SPControlMode.Edit || 
        SPContext.Current.FormContext.FormMode == SPControlMode.New)

     {
            validator.Enabled = false;
     }

}