May 2008 - Posts
I encountered an issue where I deployed a .NET 3.5 WPF application to the server.
The deployment was hosted in IIS and the prerequisites were marked with "download from the same location as my application"
The publish works and everything seems up and running.
As soon as I entered the deployment page to install the application in a machine without .NET v3.5, I got the installation window which was all nice but then I received an error.
Clicking Details revealed that it couldn't download files with ".msu" and ".msp" extensions.
The solution was to go to the IIS in the server machine, go to the website where the deployment resided and add the following MIME Types:
.msp --> application/octet-stream
.msu --> application/octet-stream
(IIS --> WebSite/Virtual Directory Properties --> HTTP Headers --> MIME Types)
The deployment in the client machine worked perfectly afterwards.
POCO - plain old c# objects.
In .NET v3.5 SP1, DataContractSerializer supports classes which aren't tagged with any serialization-related attributes. (DataContract, DataMember, Serializable)
Plus, it doesn't require the class to implement ISerializable or IXmlSerializable.
Very sweet, but do know its behavior:
These are the common grounds:
1) It will include only the fields/properties with a 'public' modifier which have both getter and a setter
2) The class must have a default parameter-less constructor
Certainly a nice addition!
I thought it would be nice to save a refence to that.
Follow this link to go to this wonderful project @CodeProject.
Via this post.
I won't elaborate so much about it, do read Lester's post in the link above.
The new feature introduces useful and simple usage to control string formatting in binding statements.
No need to use converter everywhere :)
A good thing!
<TextBox Text="{Binding Path=Double, StringFormat=F3}"/>
I decided to place it here in case I would need such a thing in the future :)
The select statement selects forum-like data model which supports paging as well. (Where comments will be below the main entry and so on)
DECLARE @Level int
DECLARE @CurrentID int
DECLARE @ParentID int
Declare @rowcount int
DECLARE @LastGroupDate DATETIME
DECLARE @LastPageID INT
CREATE TABLE #stack(
ID int ,
ParentID int ,
Level INT,
GroupDate DATETIME
)
CREATE TABLE #results(
N int IDENTITY,
ID int ,
ParentID int ,
Level int
)
DECLARE @Ignore int
DECLARE @LastID int
set @LastGroupDate= getdate()
IF @Page > 1
BEGIN
/* For pages > 1 compute how many records to ignore,
set ROWCOUNT and SELECT ID into @LastID */
SET @Ignore = @PageSize * (@Page-1)
SET ROWCOUNT @Ignore
SELECT @LastGroupDate=groupdate FROM Forums_Messages
WHERE ParentID IS NULL AND Active=1 AND NodeID=@NodeID
ORDER BY GroupDate DESC
END
ELSE
BEGIN
/* For page #1 just set rowcount to pagesize */
SET ROWCOUNT @PageSize
END
SET ROWCOUNT @PageSize
INSERT INTO #stack
SELECT ID,ParentID,1, GroupDate from Forums_Messages where
groupdate<@LastGroupDate and parentID is null and active=1 AND NodeID=@NodeID
order by groupdate desc
/* Set rowcount to @PageSize and
SELECT page for output (note the WHERE clause) */
SET ROWCOUNT 0
SET @Level = 1
WHILE @Level > 0
BEGIN
IF EXISTS (SELECT * FROM #stack WHERE Level=@Level)
BEGIN
SELECT top 1 @CurrentID=id,@ParentId=ParentID
FROM #stack WHERE Level = @Level order by GroupDate desc
INSERT INTO #results VALUES (@CurrentID,@ParentId,@Level)
DELETE FROM #stack WHERE Level = @Level AND ID = @CurrentID
INSERT #stack
SELECT ID,parentID,@level+1, GroupDate FROM Forums_Messages
WHERE parentID = @CurrentID and active=1 order by CreateDate
IF @@ROWCOUNT > 0
SET @Level = @Level + 1
END
ELSE
SELECT @Level = @Level-1
END
SELECT CEILING(COUNT(*)/CAST(@PageSize AS NUMERIC(10,3)))
FROM Forums_Messages
WHERE ParentID IS NULL AND Active=1 AND NodeID=@NodeID
select Forums_Messages.[ID]
,[NodeID]
,Forums_Messages.[ParentID]
,[GroupID]
,[UserID]
,[UserName]
,[UserEmail]
,[IsForumAdmin]
,[IsSiteAdmin]
,[Subject]
,[Body]
,[AttachmentID]
,[Active]
,[Pending]
,[CreateDate]
,[GroupDate]
,[Link1Url]
,[Link1Text]
,[Link2Url]
,[Link2Text]
,[Link3Text]
,[Link3Url] ,
(#results.level-1)*10%300 AS Level,
'<a href="{0}' + CAST([AttachmentID] AS NVARCHAR(10)) + SystemFiles_Files.FileExtension + '" target="_blank">{1}</a>' AS AttachmentLink
from #results
JOIN Forums_Messages ON #results.id = Forums_Messages.id
LEFT JOIN SystemFiles_Files ON SystemFiles_Files.ID=[AttachmentID]
order by #results.N
drop table #results
drop table #stack
Via this post from WiredPrairie blog.
The post holds links that explain approaches for extending the binding extensions.
Extending "Binding" or "BindingBase" is pretty tacky, this is due to the fact that BindingBase.ProvideValue is sealed.
The posts illustrate an elegant approach for wrapping it up and creating your own MarkUp extension to provide you with the functionality you desire.
Via this post.
If you haven't experienced it yet, there's a project template for WCF in VS2008 that if you run it inside Visual Studio, it will launch an automatic service host overriding any start up code you tried to write.
This could be annoying if you wish to disable it - as it seems, no such option in the menus or anything, pretty shame.
Well, there is a way (Did you really think otherwise? :)), it's a bit tacky - I agree, but that's until they release some sort of UI for this.
You should edit the .csproj file in the following manner:
"<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{3CC71D2E-7EC2-46B5-B985-F889B65E3DCD}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>WcfServiceLibrary1</RootNamespace>
<AssemblyName>WcfServiceLibrary1</AssemblyName>
<ProjectTypeGuids>{3D9AD99F-2412-4246-B90B-4EAA41C64699};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<StartArguments>/client:"WcfTestClient.exe"</StartArguments>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
</PropertyGroup>
The ProjectTypeGuids list is what controls these special features of projects.
Removing the {3D9AD99F-2412-4246-B90B-4EAA41C64699} entry from the list will disable automatic service hosting." (Nicholas Allen)
Service Pack 1 is here, yippy.
Obviously, this is a Beta release, thus you might want to install it on a test machine or something.
There are many cool things that come with SP1, you can read about it in the following posts:
"From a .NET Framework perspective, SP1 introduces more controls, streamlined setup, improved start-up performance, and powerful new graphics features for client development and rich data scaffolding, and improved AJAX support." (Somasegar)
There are all bunch of new stuff for Web development and WCF as well.
ScottGu - Visual Studio 2008 and .NET Framework 3.5 Service Pack 1 Beta
Mike Taulty - VS 2008 Service Pack 1 - Docs and Installation
I suggest you read Mike's post before installing SP1.
It contains many useful links and troubleshooting information.
Somasegar - Visual Studio 2008 and .NET FX 3.5 SP1 Beta available now
Steve - We are pleased to bring you new features in .NET 3.5 SP1
Scott Hanselman - VS2008 and .Net 3.5 SP1 Beta - Should You Fear This Release?
Some references I'd like to save for potential personal future use.
Client-side token cache for WCF
"WCF by default maintains a cache for security tokens per channel instance (A channel is related to a contract). Therefore, it is not possible to reuse the same token for different channel instances.. I will show the required steps to build a client-side token cache to reuse tokens obtained from a STS"
SAML - STS implementation for WCF
"I finally decided to publish a STS implementation for WCF"
Using WCF WebHttpBinding and WebGet with nicer Urls
Removing the .svc extension when hosting in IIS in .NET v3.5
Via this post.
ReaderWriterLock is used in .NET Framework in order to make synchronizations between threads to ensure thread-safety and atomic operations.
.NET v3.5 introduces a new version of this object - ReaderWriterLockSlim
The "slim" version is supposed to improve performance significantly, so if you need such locking behavior, the suggestion is - use this one.
Do note that replacing existing code will result in breaking changes -
"AcquireWriterLock becomes EnterWriterLock (or TryEnterWriterLock) for example."
Via this post by Roy Osherove.
A nice approach for working against regular expressions.
I must admit, it looks as if it would take some time to master and love.
Nice to know it's out there :)
[Test]
public void FindEmailUsingPattern()
{
var query = from match in
RegexQuery.Against("sdlfjsfl43r3490r98*(*Email@somewhere.com_dakj3j")
where match.Word.Repeat.AtLeast(1)
.Literal("@")
.Word.Repeat.AtLeast(1)
.Literal(".")
.Choice.Either(
Pattern.With.Literal("com"),
Pattern.With.Literal("net"))
.IsTrue()
select match;
foreach (var match in query)
{
Assert.AreEqual("Email@somewhere.com",match.Value);
}
}