Quite often you run into the problem, that classes do use the current HttpContext with all the permissions set. I had this problem e.g. with the PortalSiteMapProvider. It uses the regular HttpContext and there is no chance to set other properties to it. In this case you can use a temporary HttpContext to give it the SPWeb you need with the permissions of a specified user. After running your code you can turn back to the regular context.
public class TemporaryHttpContext : IDisposable
{
public TemporaryHttpContext()
{
thecurrentContext = HttpContext.Current;
HttpContext.Current = null;
}
public TemporaryHttpContext(SPWeb spweb, string userlogin) : this()
{
TemporyContext(spweb, userlogin);
}
private HttpContext thecurrentContext { get; set; }
public void TemporaryContext(SPWeb spweb, string userlogin)
{
if (spweb == null || !spweb.Exists)
{
throw new ArgumentNullException("web");
}
var request = new HttpRequest("", spweb.Url, "");
HttpContext.Current = new HttpContext(request, new HttpResponse(new StringWriter(CultureInfo.CurrentCulture)));
HttpContext.Current.Items["HttpHandlerSPWeb"] = spweb;
var wi = WindowsIdentity.GetCurrent();
if (wi != null)
{
FieldInfo fieldInfo = typeof(WindowsIdentity).GetField("m_name", BindingFlags.NonPublic | BindingFlags.Instance);
if (fieldInfo != null)
{
fieldInfo.SetValue(wi, userlogin);
}
HttpContext.Current.User = new GenericPrincipal(wi, new string[0]);
}
}
public void OldContext()
{
HttpContext.Current = thecurrentContext;
}
public void Dispose()
{
OldContext();
}
}
Afterwards just wrap your code into the temporary context like this:
TemporaryHttpContext tempcontext = new TemporaryHttpContext();
tempcontext.TemporaryContext(spweb, userloginname);
[Your code that needs a temporary context]
tempcontext.Dispose();
and then everything should work smoothly.
Dienstag, 21. Juni 2011
Dienstag, 7. Juni 2011
Webpart maintenance page
If you are running into the problem, that you added a webpart to your page and you want to remove it, because it breaks your page, then just add the query-string ?contents=1 to your URL and it will redirect you to the webpart maintenance page.
Webpart maintenance page
If you are running into the problem, that you added a webpart to your page and you want to remove it, because it breaks your page, then just add the query-string ?contents=1 to your URL and it will redirect you to the webpart maintenance page.
Mittwoch, 18. Mai 2011
Cannot generate serialization assembly ... Use /force to force an overwrite
I received this error when trying to deploy something to Sharepoint. The issue seems to be, that the dll is locked by some procedure of the IIS. Just perform in the command line a "iisreset" and try again.
Sometimes you also have to close Visual Studio and re-open after the iisreset and try again.
Sometimes you also have to close Visual Studio and re-open after the iisreset and try again.
Donnerstag, 14. April 2011
How to get the default page of a site
It is not always necessary to have the default page of a site called default.aspx.
You can use a page called mypage.aspx and use this one as default.
But when you iterate through a site, how do you find out, which page is the default one. Therefore use a code like this to find out.
First you need a SPWeb object of your site-url (e.g. your site-url is http://www.yourwebapp.com/yoursite/yoursubsite/)
string result = string.Empty;
SPSecurity.RunWithElevatedPrivileges(delegate{
SPWeb web = SPContext.Current.Site.OpenWeb("yoursite/yoursubsite");
result = web.RootFolder.WelcomePage;
});
The result value will be "Pages/mypage.aspx".
You can use a page called mypage.aspx and use this one as default.
But when you iterate through a site, how do you find out, which page is the default one. Therefore use a code like this to find out.
First you need a SPWeb object of your site-url (e.g. your site-url is http://www.yourwebapp.com/yoursite/yoursubsite/)
string result = string.Empty;
SPSecurity.RunWithElevatedPrivileges(delegate{
SPWeb web = SPContext.Current.Site.OpenWeb("yoursite/yoursubsite");
result = web.RootFolder.WelcomePage;
});
The result value will be "Pages/mypage.aspx".
Dienstag, 29. März 2011
Variations Display Name vs. Label
Always good to know.
Display Name is the name shown in the structure tree and the name of the site.
The label is the name of the variation.
Display Name is the name shown in the structure tree and the name of the site.
The label is the name of the variation.
Montag, 28. März 2011
How to: c# code in powershell script
I was looking for a way to add C# code to a powershell script, because sometimes you are not able to run everything with powershell.
It works like this:
first reference to the assemblies your code uses:
$referencingassemblies = (
"Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" ,
"Microsoft.SharePoint.Publishing, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c",
"System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
)
Then insert the source and store it in a variable. Be aware to have all the assemblies you are using referenced in your variable above:
$mysource = @"
using Microsoft.SharePoint.Publishing.Administration;
using Microsoft.SharePoint;
using System;
using System.Data;
using System.Xml;
using Microsoft.SharePoint.Publishing;
namespace MyNamespace
{
public static class MyClass
{
public static void Do(SPWeb rootWeb)
{
Console.WriteLine(rootWeb.Url);
Console.WriteLine(rootWeb.Title);
}
}
}
"@
Then add the code to the memory and call your code:
#Here you just add the assemblies and the code to the memory
Add-Type -ReferencedAssemblies $referencingassemblies -TypeDefinition $mysource -Language CSharp
#For this sample I will need another assembly
[system.reflection.assembly]::LoadWithPartialName("Microsoft.Sharepoint")
#Load the site-object of your webapp
$site = New-Object Microsoft.SharePoint.SPSite("http://www.mydomain.com")
#Use the rootweb of your site
$root = $site.rootweb
#Overload to your C# method. To call the method use in brakets the namespace and class.
[MyNamespace.MyClass]::Do($root)
In this sample above you already see how to combine powershell code with C# code. If you change something in your C# code, then close the powershell window and re-open, so the code will be loaded/added to memory again. Otherwise you won't see the changes you made.
You can copy the code-segments above into one powershell script file and give it a try.
It works like this:
first reference to the assemblies your code uses:
$referencingassemblies = (
"Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" ,
"Microsoft.SharePoint.Publishing, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c",
"System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
)
Then insert the source and store it in a variable. Be aware to have all the assemblies you are using referenced in your variable above:
$mysource = @"
using Microsoft.SharePoint.Publishing.Administration;
using Microsoft.SharePoint;
using System;
using System.Data;
using System.Xml;
using Microsoft.SharePoint.Publishing;
namespace MyNamespace
{
public static class MyClass
{
public static void Do(SPWeb rootWeb)
{
Console.WriteLine(rootWeb.Url);
Console.WriteLine(rootWeb.Title);
}
}
}
"@
Then add the code to the memory and call your code:
#Here you just add the assemblies and the code to the memory
Add-Type -ReferencedAssemblies $referencingassemblies -TypeDefinition $mysource -Language CSharp
#For this sample I will need another assembly
[system.reflection.assembly]::LoadWithPartialName("Microsoft.Sharepoint")
#Load the site-object of your webapp
$site = New-Object Microsoft.SharePoint.SPSite("http://www.mydomain.com")
#Use the rootweb of your site
$root = $site.rootweb
#Overload to your C# method. To call the method use in brakets the namespace and class.
[MyNamespace.MyClass]::Do($root)
In this sample above you already see how to combine powershell code with C# code. If you change something in your C# code, then close the powershell window and re-open, so the code will be loaded/added to memory again. Otherwise you won't see the changes you made.
You can copy the code-segments above into one powershell script file and give it a try.
Donnerstag, 24. März 2011
Always needed information
I often can't recall, which Request.Url property returns what string. So I have published here now the most usefull ones:
Request.Url.AbsolutePath: /test/test34/testpage.aspx
Request.Url.Host: localhost
Request.Url.Query: ?test1=true&test2=false&test4=string
Segments: /
Segments: test/
Segments: test34/
Segments: testpage.aspx
Request.Url.AbsoluteUri: http://localhost:1234/test/test34/testpage.aspx?test1=true&test2=false&test4=string
Request.RawUrl: /test/test34/testpage.aspx?test1=true&test2=false&test4=string
Request.Url.ToString(): http://localhost:1234/test/test34/testpage.aspx?test1=true&test2=false&test4=string
Request.Url.AbsolutePath: /test/test34/testpage.aspx
Request.Url.Host: localhost
Request.Url.Query: ?test1=true&test2=false&test4=string
Segments: /
Segments: test/
Segments: test34/
Segments: testpage.aspx
Request.Url.AbsoluteUri: http://localhost:1234/test/test34/testpage.aspx?test1=true&test2=false&test4=string
Request.RawUrl: /test/test34/testpage.aspx?test1=true&test2=false&test4=string
Request.Url.ToString(): http://localhost:1234/test/test34/testpage.aspx?test1=true&test2=false&test4=string
Donnerstag, 3. März 2011
Powershell - site-defintion installation
I had the following problem. I created a powershell script to install a solution, that contains a site-defintion to a web-application. The issue I ran into was, that the template I am using to create the SPSite in this web-application was not recognized. That means everytime I tried to use this custom template, I received the error ""
On the web I found the cause for this error. The template is not recognized in this session. When you open parallel another powershell window and list the templates (get-spwebtemplates), then you see your template. But not in the host window.
To avoid this error, you have to start another powershell process out of the host window. There you can work with the template.
Be aware to add a sleep function, because the install of the solution with the site-definition needs to be terminated before being able to work with it.
You can copy the host-script into a file called hostscript.ps1 and the new window script into a file called window.ps1
---- your host script ------- (rename the %% variables with your parameters)
#This function installs the solution
function InstallSolution([string] $solutionname, [string] $url)
{
#Check if solution already exists
$solution = Get-SPSolution | where-object {$_.Name -eq $solutionname}
if ($solution -eq $null)
{
#If it is not added yet. Add it and then deploy it.
Add-SPSolution -LiteralPath "%your solution directory%\$solutionname"
Install-SPSolution –Identity $SolutionName –WebApplication "http://$url" –GACDeployment
}
$solution = Get-SPSolution | where-object {$_.Name -eq $solutionname}
#Run the sleeper. It will wait until the solution is finally deployed
do
{
Start-Sleep -Seconds 10
}
until ($solution.Deployed -eq $true)
}
#Enter your parameters here
$webapplicationname = %webapplication-name%
$webapplicationport = %webapplication-port%
$hostheader = %host-header%
$url = %url%
$iisdirectory = %iis-directory%
$apppool = %app-pool%
$apppoolaccount = %app-pool-account%
$databasename = %database-name%
$databaseserver = %database-server%
$sitecollectionadmin = %site-collection-admin%
#Create a new web-application with the above mentioned parameters
New-SPWebApplication -Name $webapplicationname -Port $webapplicationport -AllowAnonymousAccess:$true -HostHeader $hostheader -URL "http://$url" -Path $iisdirectory -ApplicationPool $apppool -ApplicationPoolAccount (Get-SPManagedAccount $apppoolaccount) -DatabaseName $databasename -DatabaseServer $databaseserver
#Call the function above and overload the needed parameters
InstallSolution "%my solution name%", $url
#Here is your template-name. If you don't know yours, then just install the solution and run get-spwebtemplate. It lists all templates. Yours is then supposed to be there as well with the correct # value.
$mydefinitiontemplate = "%My Template%#0"
#Here the new console powershell-window opens.
$newwindow = New-Object system.Diagnostics.ProcessStartInfo
$newwindow.FileName = "powershell.exe"
#I am overloading some variables just to show, how this works
$newwindow.Arguments = "-noexit %your install directory%\window.ps1 $url $mydefinitiontemplate $sitecollectionadmin"
$process = [system.Diagnostics.Process]::Start($newwindow)
#The process will wait, until the window will exit and close
$process.waitforexit()
#Finally just reset the iis
iisreset
---- end host script -------
---- your new window script ------- (rename the %% variables with your parameters)
#Here you catch the overloaded parameters and fill some variables with it
$url = $args[0]
$mytemplatename = $args[1]
$sitecollectionadmin = $args[2]
#Create the new site-collection
New-SPSite -URL "http://$url" -OwnerAlias $sitecollectionadmin -Name %your site name% -Template $mytemplatename
#Tell the host-window, that this window closed
$Host.SetShouldExit(0)
---- end new window script -------
Then save those files somewhere and open powershell and type:
[your path of the hostscript.ps1 file]\hostscript.ps1
This script now creates the web-application, installs the solution with the site-definition and as soon as the solution is deployed, it opens a new console window, to run the second script, that creates a new site-collection in the web-application with the site-definition template you deployed. The window closes afterwards and the host-window then does an iisreset.
It took me quite long to find out about this speciality with site-definition solution deployment and using the template afterwards when creating a site-collection.
On the web I found the cause for this error. The template is not recognized in this session. When you open parallel another powershell window and list the templates (get-spwebtemplates), then you see your template. But not in the host window.
To avoid this error, you have to start another powershell process out of the host window. There you can work with the template.
Be aware to add a sleep function, because the install of the solution with the site-definition needs to be terminated before being able to work with it.
You can copy the host-script into a file called hostscript.ps1 and the new window script into a file called window.ps1
---- your host script ------- (rename the %% variables with your parameters)
#This function installs the solution
function InstallSolution([string] $solutionname, [string] $url)
{
#Check if solution already exists
$solution = Get-SPSolution | where-object {$_.Name -eq $solutionname}
if ($solution -eq $null)
{
#If it is not added yet. Add it and then deploy it.
Add-SPSolution -LiteralPath "%your solution directory%\$solutionname"
Install-SPSolution –Identity $SolutionName –WebApplication "http://$url" –GACDeployment
}
$solution = Get-SPSolution | where-object {$_.Name -eq $solutionname}
#Run the sleeper. It will wait until the solution is finally deployed
do
{
Start-Sleep -Seconds 10
}
until ($solution.Deployed -eq $true)
}
#Enter your parameters here
$webapplicationname = %webapplication-name%
$webapplicationport = %webapplication-port%
$hostheader = %host-header%
$url = %url%
$iisdirectory = %iis-directory%
$apppool = %app-pool%
$apppoolaccount = %app-pool-account%
$databasename = %database-name%
$databaseserver = %database-server%
$sitecollectionadmin = %site-collection-admin%
#Create a new web-application with the above mentioned parameters
New-SPWebApplication -Name $webapplicationname -Port $webapplicationport -AllowAnonymousAccess:$true -HostHeader $hostheader -URL "http://$url" -Path $iisdirectory -ApplicationPool $apppool -ApplicationPoolAccount (Get-SPManagedAccount $apppoolaccount) -DatabaseName $databasename -DatabaseServer $databaseserver
#Call the function above and overload the needed parameters
InstallSolution "%my solution name%", $url
#Here is your template-name. If you don't know yours, then just install the solution and run get-spwebtemplate. It lists all templates. Yours is then supposed to be there as well with the correct # value.
$mydefinitiontemplate = "%My Template%#0"
#Here the new console powershell-window opens.
$newwindow = New-Object system.Diagnostics.ProcessStartInfo
$newwindow.FileName = "powershell.exe"
#I am overloading some variables just to show, how this works
$newwindow.Arguments = "-noexit %your install directory%\window.ps1 $url $mydefinitiontemplate $sitecollectionadmin"
$process = [system.Diagnostics.Process]::Start($newwindow)
#The process will wait, until the window will exit and close
$process.waitforexit()
#Finally just reset the iis
iisreset
---- end host script -------
---- your new window script ------- (rename the %% variables with your parameters)
#Here you catch the overloaded parameters and fill some variables with it
$url = $args[0]
$mytemplatename = $args[1]
$sitecollectionadmin = $args[2]
#Create the new site-collection
New-SPSite -URL "http://$url" -OwnerAlias $sitecollectionadmin -Name %your site name% -Template $mytemplatename
#Tell the host-window, that this window closed
$Host.SetShouldExit(0)
---- end new window script -------
Then save those files somewhere and open powershell and type:
[your path of the hostscript.ps1 file]\hostscript.ps1
This script now creates the web-application, installs the solution with the site-definition and as soon as the solution is deployed, it opens a new console window, to run the second script, that creates a new site-collection in the web-application with the site-definition template you deployed. The window closes afterwards and the host-window then does an iisreset.
It took me quite long to find out about this speciality with site-definition solution deployment and using the template afterwards when creating a site-collection.
Mittwoch, 23. Februar 2011
... Failed to create receiver object from assembly ... value cannot be null
I had this error, when I deployed a custom site-definition and then tried to create a new site-collection. The error was caused by a code I deployed some time before. I retracted those solutions and then deployed from scratch. It is important to clean out with old "not used" solutions. Also check in the Central-Administration, if all not used solutions are removed. After the new deployment, everything went smooth.
It could also be, that there is somewhere an assembly, that is called the same or does have similar namespaces.
It could also be, that there is somewhere an assembly, that is called the same or does have similar namespaces.
Abonnieren
Posts (Atom)