Use Fiddler to monitor IIS request

by Viktor 11. November 2010 10:40

I often use Fiddler to debug or just see what is sent between the browser and server but today I needed a tool to see what EPiServer sent to a remote site and received back.
After an hour of searching and not finding anything I liked I come upon a blog post (using-fiddler-with-iis) that solved everything for me, just set the application pool to run as your user and all requests from your code to external servers will show up in Fiddler!

Tags: , ,

Move content to another language in EPiServer

by Viktor 1. November 2010 10:25

In the latest project I was involved in we created a site that would be in Norwegian, during the development we did all texts in English and as the site would not be globalized we did no changes in in EPiServer, just a standard installation. When we then received the Norwegian translations we noticed that we had made the site for the English language branch and was not able to get the Norwegian translations to show up on the site.

With the help of this blog post, http://andrewgunn.blogspot.com/2008/01/change-page-language-in-episerver.html, we ware able to solve the problem.
The first thing we did was enable Norwegian in Admin mode.
Then we ran the following SQL script in the EPiServer database,

DECLARE @PageID INT
DECLARE @RowNum INT 
DECLARE PageList CURSOR FOR
	SELECT pkID FROM tblPage
OPEN PageList
FETCH NEXT FROM PageList INTO @PageID
WHILE @@FETCH_STATUS = 0
BEGIN
	DECLARE @OriginalLanguageBranchID INT
	DECLARE @NewLanguageBranchID INT
	DECLARE @NewLanguageID NVARCHAR(3)
		 
	SET @OriginalLanguageBranchID = Y
	SET @NewLanguageBranchID = Z
	SET @NewLanguageID = 'NO'
		 
	UPDATE tblPageLanguage
	SET fkLanguageBranchID = @NewLanguageBranchID, fkLanguageID = @NewLanguageID
	WHERE fkPageID = @PageID
		 
	UPDATE tblPage
	SET fkMasterLanguageBranchID = @NewLanguageBranchID, fkLanguageID = @NewLanguageID
	WHERE pkID = @PageID 
		 
	UPDATE tblProperty
	SET fkLanguageBranchID = @NewLanguageBranchID
	WHERE fkPageID = @PageID and fkLanguageBranchID = @OriginalLanguageBranchID
		 
	EXEC editPageVersionList @PageID = @PageID, @SID = NULL

	FETCH NEXT FROM PageList INTO @PageID
END
CLOSE PageList
DEALLOCATE PageList
The importent parts here are
SET @OriginalLanguageBranchID = Y
SET @NewLanguageBranchID = Z
SET @NewLanguageID = 'NO'

Here you set the id of the language you want to change from, the id of the language you want to change to and the new language id, in this case 'NO'.
Run this script in your EPiServer database to move all content from the old language to the new language.
All information you need can be found in the table tblLanguageBranch,

SELECT pkID, LanguageID FROM tblLanguageBranch

When this is done you will get a warning in EPiServer telling you that the page is not available in your current language, to into Admin mode and turn on Globalization, in the edit mode select the root page and language options for this page, change the default language to your new language, turn off Globalaization.

Finished! The site had now been transformed from a English site to a Norwegian one.

Tags: ,

Development

Accessing ASP CheckBoxList and RadioButtonList values with JavaScript

by Andreas Nylin 3. June 2010 13:26

One of the worst controls in the ASP.NET library is the CheckBoxList (or the RadioButtonList). I just can't understand why they have implemented it the way they did. The thing that annoys me the most is that it doesn't render the value of each item in the list in the HTML code. I will describe a workaround for this in this post.

Let's start by creating a simple CheckBoxList:

<asp:CheckBoxList ID="MyCheckBoxList" RepeatLayout="Flow"  runat="server">
   <asp:ListItem Text="One" Value="1" />
   <asp:ListItem Text="Two" Value="2" />
</asp:CheckBoxList>

This is the generated HTML code:

<span id="ctl00_MyCheckBoxList">
   <input id="ctl00_MyCheckBoxList_0" type="checkbox" name="ctl00$MyCheckBoxList$0" />
   <label for="ctl00_MyCheckBoxList_0">One</label><br />
   <input id="ctl00_MyCheckBoxList_1" type="checkbox" name="ctl00$MyCheckBoxList$1" />
   <label for="ctl00_MyCheckBoxList_1">Two</label>
</span>

Note that no value attribute is generated for the input elements even though we specified a value.

If you try to add it as an attribute nothing will happen. This will generate the same HTML code:

foreach (ListItem li in MyCheckBoxList.Items)
{
   li.Attributes.Add("value", li.Value);
}

However, if we change the attribute to something else than value a span will be added to wrap the input checkbox element.

foreach (ListItem li in MyCheckBoxList.Items)
{
   li.Attributes.Add("id", li.Value);
}

This is the generated HMTL code:

<span id="ctl00_MyCheckBoxList">
   <span id="1">
      <input id="ctl00_MyCheckBoxList_0" type="checkbox" name="ctl00$MyCheckBoxList$0" />
      <label for="ctl00_MyCheckBoxList_0">One</label>
   </span><br />
   <span id="2">
      <input id="ctl00_MyCheckBoxList_1" type="checkbox" name="ctl00$MyCheckBoxList$1" />
      <label for="ctl00_MyCheckBoxList_1">Two</label>
   </span>
</span>

This is really odd but now we can at least access the checkbox value on the client side. You could do it like this with jQuery:

$("#<%= MyCheckBoxList.ClientID %>").find(":checkbox").click(function () {
   alert($(this).parent().attr("id"));
});

Or with ASP.NET AJAX:

var checkBoxList = $get("<%= MyCheckBoxList.ClientID %>");
var checkBoxes = checkBoxList.getElementsByTagName("input");
for (var i = 0; i < checkBoxes.length; i++) {
   $addHandler(checkBoxes[i], "click", function () {
      alert(this.parentNode.id);
   });
}

Tags: , ,

Development

Kill all connections to a database in SQL Server

by Viktor 19. May 2010 08:32
When you want to rename a database or something like that you need to get exclusive access to the database and it can be hard to get this exclusive access because there are always someone who has a connection. This script will kill all connections to a database, just replace "DATABASE_NAME" with the name of the database you want to kill connections for,
DECLARE @SQL VARCHAR(8000)
 
SELECT @SQL=COALESCE(@SQL,'')+'Kill '+CAST(spid AS VARCHAR(10))+ '; ' 
FROM sys.sysprocesses 
WHERE DBID=DB_ID('DATABASE_NAME')
 
EXEC(@SQL) 

Tags: ,

System.UriFormatException: Invalid URI: There is an invalid sequence in the string. exception when going to edit on page with composer

by tomasu 22. April 2010 14:32

Today when we were setting up an old EPiServer 5.1 SP1 site we got some strange errors so I turned on the logging in EPiServer. I got everything to work except for the composer edit on page where I recived the error below.

After doing some debuggning with Reflector Pro inside the EPiServer assembly I realised that it was when EPiServer.Web.PermanentLinUtility.GetPageReference(UrlBuilder mappedUrl) was trying to do some logging it failed. The first thing that this method does is to check for some logging settings and then do some logging.

if (_log.IsInfoEnabled)
{
    _log.InfoFormat("ReparsePageUrl for Url = {0}", (mappedUrl == null) ? "(NULL)" :  mappedUrl.ToString());
}


The part which fails is mappedUrl.ToString().

I haven't bothered to analyze why the ToString() fails. I just turned down the logging so that it won't log that.
If anyone has an idea why it's failing, please comment.

 

Server Error in '/' Application.

Invalid URI: There is an invalid sequence in the string.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.UriFormatException: Invalid URI: There is an invalid sequence in the string.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[UriFormatException: Invalid URI: There is an invalid sequence in the string.]
System.Uri.UnescapeString(Char* pStr, Int32 start, Int32 end, Char[] dest, Int32& destPosition, Char rsvd1, Char rsvd2, Char rsvd3, UnescapeMode unescapeMode, UriParser syntax, Boolean isQuery, Boolean readOnlyConfig) +1332
System.Uri.UnescapeString(String input, Int32 start, Int32 end, Char[] dest, Int32& destPosition, Char rsvd1, Char rsvd2, Char rsvd3, UnescapeMode unescapeMode, UriParser syntax, Boolean isQuery, Boolean readOnlyConfig) +73
System.Uri.UnescapeDataString(String stringToUnescape) +152
EPiServer.UrlBuilder.ToString() +15
EPiServer.Web.PermanentLinkUtility.GetPageReference(UrlBuilder mappedUrl) +48
EPiServer.Web.FriendlyHtmlRewriteToExternal.HtmlRewriteUrl(UrlBuilder internalUrl, UrlBuilder externalUrl, UrlBuilder url, Encoding encoding, Object& internalObject) +15
EPiServer.Web.FriendlyHtmlRewriteToExternal.rewritePipe_HtmlRewriteUrl(Object sender, HtmlRewriteEventArgs e) +274
EPiServer.Web.RewritePipe.OnHtmlRewriteUrl(HtmlRewriteEventArgs e) +19
EPiServer.Web.HtmlRewritePipe.WriteElement(MyHtmlRewriteEventArgs e, SgmlReader reader, TextWriter writer) +394
EPiServer.Web.HtmlRewritePipe.RewriteToEnd(TextReader reader, TextWriter writer) +2008
EPiServer.Web.HtmlRewriteStream.Close() +165
System.Web.HttpWriter.FilterIntegrated(Boolean finalFiltering, IIS7WorkerRequest wr) +497
System.Web.HttpResponse.FilterOutput() +119
System.Web.CallFilterExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +47
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75


Version Information: Microsoft .NET Framework Version:2.0.50727.4927; ASP.NET Version:2.0.50727.4927

 

Tags: , , , ,

Development

Dropit redefines MVC: Presents V for classic ASP/VBScript

by scott.phrank 1. April 2010 11:27

Dropit has spent the last couple of months building a MVC framework for classic asp, or VBScript, and we finally feel that it's ready for release.

The biggest problem we have encountered during the development phase is the lack of objects in VBScript, hence we have discarded the M in MVC.

We have also decided to ignore the C since controllers and VBScript don't match.

But we have built a couple of Views for VBScript, please download them here.

Views.rar (42.06 kb)

Tags:

Development

Blog Page Provider for EPiServer CMS

by Viktor 25. March 2010 15:04

Blog Page Provider is a example project I have created to try out the page provider in EPiServer

As the name may suggest this is a EPiServer page provider for blogs that has the ability to create a blog page in EPiServer that connects with a blog and lists all blogs, posts and comments connected to that account as EPiServer pages. You can also create blog posts and comments in EPiServer by creating "Post" or "Comment" pages.

The page providers are added dynamically to EPiServer so there is no configuration to setup the providers just create a page of the right type ("Blog - Settings") in EPiServer and the page provider will be added for you.

Support for different blog types is handled by blog providers, right now there are two providers, one for Blogger and the other for WordPress. You can create your own provider for other blogs by just implementing the interfaces in the Dropit.BlogPageProvider.Blog namespace and add the provider in web.config.

You can find more information about the project and all code over at Codeplex, Blog Page Provider

Have fun with it!

Blog Post Provider in three short steps

Blog post both in EPiServer and on Blogger

Create a new blog post in EPiServer

The created blog post is shown both in EPiServer and on blogger

Tags: , ,

Development

Updated Checklist for deploying EPiServer sites

by Andreas Nylin 25. March 2010 10:35

The checklist has been updated with info on EPiServerLog.config and more detailed descriptions. View the updated list in the checklist post or download the PDF version.

Tags:

Development

Testing your website on different IE versions

by markus.svart 23. March 2010 12:57

In this blog post I'm writing about a few ways to debug and test websites for Internet Explorer (IE).

Windows XP mode

If you have Windows 7 (Professional, Enterprise or Ultimate) installed on your computer you can download Windows XP-mode for free from Microsoft. Windows XP mode is a Virtual machine that lets you run Windows XP on your Windows 7 computer. More information can be found at Microsoft’s Virtual PC site.

The best thing with XP-mode is that it is (at least now) shipped with IE6 as standard web browser. In this way you have the "original" way to test your sites on IE6.
Just don't allow XP-mode to install updates automatically, because it will overwrite IE6 with IE7.

If you want to test your sites on IE7 you can download a standalone version of IE. I prefer Tradesoft’s version which can be downloaded from Tradesoft's home page.

Using IETester

Another way to test different versions of IE is to use IETester. In this program you open tabs for different IE versions (from 5.5 to 8).
Windows 7 is supported in the latest release. In my opinion IETester works quite fine and in most of the cases renders the pages like the real IE-versions.
But once I did find an error in absolutely positioned CSS, so be aware! :)

DebugBar

I also want to give you a tip about DebugBar. It an add-on for IE that allows you to debug the site you are visiting. Just remember to activate the add-on by right clicking on the taskbar, selecting DebugBar and clicking the Activate button.

Tags:

Design | Front end

EPiServer Composer page is missing a Shadowpage, or a reason why you can’t create functions

by Fredrik Karlsson 22. March 2010 21:10

The problem

You drag a function onto your EPiServer composer page:
Drag

You drop the function in a content area and watch the spinning effect:
drop

The function just disappear!
Missing

Some background

As you probably know, each Composer page is actually a lot of EPiServer pages. Each function is an EPiServer page and each Function type is a EPiServer pagetype. So when you create a new function, you actually creates a new EPiServer page. That page is created in the EPiServer tree under a special page called a Shadow page. The shadow page is a container for each composer page and exists in order to make sure that all composer functions are not created on the same level, since that would have a serious performance impact.

Some debugging

The best way to start is to enable logging in Composer and you will probably see something like this:

2010-03-22 20:35:42,022 [23] ERROR Dropit.Extension.UI.Edit.CreateContentFunction [(null)] - Dropit.Extension.UI.Edit.CreateContentFunction: Page 737 was not found
EPiServer.Core.PageNotFoundException: Page 737 was not found
   at EPiServer.DataAccess.PageLoadDB.LoadPageInternal(PageReference pageLink, Int32 languageBranchId, IDataReader reader)
   at EPiServer.DataAccess.PageLoadDB.<>c__DisplayClass1.b__0()
   at EPiServer.DataAccess.DataAccessBase.<>c__DisplayClass1`1.b__0()
   at EPiServer.DataAccess.DatabaseFactory.Execute[TResult](Action`1 method)
   at EPiServer.DataAccess.DataAccessBase.Execute[TResult](Action`1 action)
   at EPiServer.Core.PageProviderBase.<>c__DisplayClass4.b__3()
   at EPiServer.Core.OptimisticCache`1.Read(String cacheKey, ReadAndCacheObject`1 readAndCacheObject)
   at EPiServer.Core.PageProviderBase.GetPageInternal(PageReference pageLink, ILanguageSelector selector)
   at EPiServer.Core.PageProviderBase.GetPage(PageReference pageLink, ILanguageSelector selector)
   at EPiServer.DataFactory.GetPage(PageReference pageLink, ILanguageSelector selector)
   at EPiServer.Core.PageLanguageSettingsTree.GetClosestSetting(PageReference pageLink)
   at EPiServer.Core.PageLanguageSettingsTree.Get(PageReference pageLink)
   at EPiServer.Core.PageLanguageSettingsTree.Get(PageReference pageLink, String languageBranch)
   at EPiServer.Core.LanguageSelector.LoadLanguage(LanguageSelectorContext context)
   at EPiServer.Core.CreatePageData.DefaultPageDataLanguage(Int32 pageTypeID, PageReference parentPageLink, ILanguageSelector selector, IList`1 existingLanguages)
   at EPiServer.Core.PageProviderBase.GetDefaultPageData(PageReference parentPageLink, Int32 pageTypeID, ILanguageSelector selector)
   at EPiServer.DataFactory.GetDefaultPageData(PageReference parentPageLink, Int32 pageTypeID, ILanguageSelector selector)
   at Dropit.Extension.Controllers.ContentFunctionDataManager.CreateContentFunctionData(PageReference extensionPageLink, Int32 contentFunctionTypeId, AccessLevel accessLevel)
   at Dropit.Extension.Controllers.ContentFunctionDataManager.CreateContentFunctionData(PageReference extensionPageLink, Int32 contentFunctionTypeId)
   at Dropit.Extension.Core.ContentFunctionData.Create(PageReference extensionPageLink, Int32 functionTypeId)
   at Dropit.Extension.UI.Edit.CreateContentFunction.Page_Load(Object sender, EventArgs e)

Ok, so page 737 is missing. A liitle bit up in the log file, we see this:

2010-03-22 20:35:41,960 [23] INFO  Dropit.Extension.Core.Serializer              [(null)] - Dropit.Extension.Core.Serializer: <?xml version="1.0" encoding="utf-8"?>
<specializedextensionpagedata>
  <pagestructure shadowguid="06ad9f3b-ea46-414a-b45d-198b03817a5b"
	guid="59b27f7d-c2dc-4a06-8251-2bb83e1967e9" 
	remotesite="" 
	wid="3326" 
	pid="2171" 
	sid="737">
    <ca id="SideContent" desc="SideContent content" />
    <ca id="TopContent" desc="The top content area" />
    <ca id="MainTopContent" desc="The main content top area" />
    <ca id="MainBottomContent" desc="The main content bottom area" />
    <ca id="SecondaryContent" desc="Secondary content" />
    <ca id="BottomContent" desc="The bottom content area" />
  </pagestructure>
  <content><!-- Empty -->
</specializedextensionpagedata>

As you can see, the sid attribute has the value 737. Sid stands for Shadow ID, or the page that will work as a shadow page for this composer page. And it is missing!

The fix

Just run this code to fix this:

var extensionpagetypes = Dropit.Extension.Global.ListExtensionPageTypes();
var pages = EPiServer.DataFactory.Instance.GetDescendents(PageReference.RootPage);
var composerpages = from p in pages
					from pt in extensionpagetypes
					where EPiServer.DataFactory.Instance.GetPage(p).PageTypeID == pt.ID // 10610
					select EPiServer.DataFactory.Instance.GetPage(p);

PageReference newShadowPage;
PageReference existingShadowPage;
foreach (var composerPage in composerpages)
{
	var composerPageData = Dropit.Extension.Core.ExtensionPageData.Load(composerPage.PageLink);

	// This is always true, bug in composer?
	//if (composerPageData.ShadowPageLink == PageReference.EmptyReference)
	if (composerPageData != null)
	{
		try
		{
			existingShadowPage = new PageReference(composerPageData.ShadowPageID);
			GetPage(existingShadowPage);
		}
		catch (PageNotFoundException ex)
		{
			// The shadowpage is missing
			// Lets create it
			newShadowPage = Dropit.Extension.Controllers.ShadowPageManager.Instance.NewShadowPage(composerPageData.PageLink);
			Dropit.Extension.Controllers.PageDataManager.UpdateShadowPageID(composerPage, newShadowPage);
		}
		catch (Exception)
		{
			// Something else is wrong
			// Lets skip it...
		}
	}
}

Why is this necessary?

Former versions of Composer had a bug when you copied a composer page. It didn’t generate a new shadowpage for the new page. And when you deleted the old page, the shadow page was deleted as well, simply leaving the newly copied page without a shadow page.

Tags: , , ,

Development

Creative Commons License
This work is licensed under a Creative Commons Attribution-Share Alike 2.5 Sweden License.


Welcome to the Dropit blog!

Here we, the people that work at Dropit, will write about stuff that interests us. For example web development, especially with .NET and EPiServer - but we'll also talk about other techniques that interest us, marketing on the web, social phenomenons, pop culture, games and software development in general.