Wednesday 25 April 2012

FtpWebRequest: working with files outside of home folder

Something I ran recently against is the need to upload a file to FTP server using the FtpWebRequest class but to a location that is outside of my ftp user home folder. One would think this is no problem, but I found different.

The trick is in the URI being used. If you use ftp://server/folder1/folder2/filename.ext , what the FTP client does it issues a PWD command to the serer to find out the current folder. In this case the server will respond with your home folder like "/home/username/". Then the client will append this home folder to the folder you requested and will do CWD to "/home/username/folder1/folder2/" which in my case does not exist as my folder on the server is simply /folder1/folder2/.

So what to do now? I tried my luck and was amased with how much luck I have as it worked from the first attemtp - it is as simple as this: just specify the path in the follwing way ftp://server//folder1/folder2/filename.ext - see the two // after the server name ? This tells the client to ignore the user home folder and just do a CDW to the "/folder1/folder2/"

I hope this will help and save some time to some of you.

Tzanimir


Wednesday 18 August 2010

Retrieving Actual .aspx File Path when using Url Routing

In the last few days I was almost driven to madness, trying to get in code the Path of the actual .aspx file servicing a request that was routed trough the new ASP.NET 4.0 URL Routing. The problem was that I wanted to retrieve a LocalResouce for custom control from the page resource files. After a lot of searching, I managed to find a way myself.

System.String Path = ((System.Web.Routing.PageRouteHandler)(((System.Web.Routing.Route)(HttpContext.Current.Request.RequestContext.RouteData.Route)).RouteHandler)).VirtualPath;
 
then to get the LocalResourceObject you do:
 System.String localResource = HttpContext.GetLocalResourceObject(path, LocalResourceName).ToString();

I hope this helps some of you.


Tzanimir

Monday 28 June 2010

BadImageFormatException with 32-bit DLLs on 64-bit server in ASP.NET .NET 4.0

I faced a problem after upgrading my ASP.NET site from .NET 3.5 to 4.0 where I started getting the following exception:

“BadImageFormatException: Could not load file or assembly '<32 bit Assembly>' or one of its dependencies. An attempt was made to load a program with an incorrect format.”

After searching for a while in internet, the problem was clear – my 64 bit windows is refusing to load the 32bit DLL when starting my ASP.NET application. The only problem left was how to fix this. Looking little bit more, the solution was very simple (for the installation of IIS7 I am running)

Under ‘Internet Information Services (IIS) Manager"’ –> ‘Application Pools’ locate the pool used by your application (The default name will be ‘ASP.NET v4.0’). Right Click it and open the ‘Advanced Settings’. Under ‘General’ find the ‘Enable 32-Bit Applications’ and change the setting to ‘True’

That's it.

Hope this helps.

Tzanimir

Wednesday 16 September 2009

Silverlight: Passing constructor parameters when creating objects from dynamically loaded assemblies.

In my current project I faced the problem that when using the Assembly.CreateInstance in Silverlight , constructor parameters cannot be directly passed.

The workaround I found is very simple and uses the Activator.Create instance in the following manner:

System.Object new_object = Activator.CreateInstance(asm.GetType("SomeNamespace.SomeType"), new Object[]{"param1","param2"});


I hope this helps somebody.



Tzanimir

Thursday 20 August 2009

Silverlight Application – Access to Server side variables

The question was asked in the Silvelright.net forum how can the Silverlight application get the user IP address. One of the ways this can be done trough the Silverlight initParams.

Here is a working example that gives the application copy of the REMOTE_ADDR and HTTP_USER_AGNET proeprties from the Request.ServerVariables on the server.

To pass parameters to the Silverlight application a new parameter with name initialParams need to be added to the object that hosts the application:

<param name="initParams" value='ip=<%=(Request.ServerVariables["REMOTE_ADDR"])%>,agent=<%=(Request.ServerVariables["HTTP_USER_AGENT"])%>' />



Practically any parameter can be made available. Each parameter is passed as “key”=”value” pair and the parameters are separated by a comma (“,”). The only issue that needs to be handled is when the data contains a comma – then it needs to be escaped.



Here is a working example code (testpage.aspx):



<%@ Page Language="C#" AutoEventWireup="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<
html xmlns="http://www.w3.org/1999/xhtml" >
<
head runat="server">
<
title>silverlight.net</title>
<
style type="text/css">
html, body {
height: 100%;
overflow: auto;
}
body {
padding: 0;
margin: 0;
}
#silverlightControlHost {
height: 100%;
text-align:center;
}
</style>
<
script type="text/javascript" src="Silverlight.js"></script>
<
script type="text/javascript">
function
onSilverlightError(sender, args) {
var appSource = "";
if (sender != null && sender != 0) {
appSource = sender.getHost().Source;
}

var errorType = args.ErrorType;
var iErrorCode = args.ErrorCode;

if (errorType == "ImageError" || errorType == "MediaError") {
return;
}

var errMsg = "Unhandled Error in Silverlight Application " + appSource + "\n" ;

errMsg += "Code: "+ iErrorCode + " \n";
errMsg += "Category: " + errorType + " \n";
errMsg += "Message: " + args.ErrorMessage + " \n";

if (errorType == "ParserError") {
errMsg += "File: " + args.xamlFile + " \n";
errMsg += "Line: " + args.lineNumber + " \n";
errMsg += "Position: " + args.charPosition + " \n";
}
else if (errorType == "RuntimeError") {
if (args.lineNumber != 0) {
errMsg += "Line: " + args.lineNumber + " \n";
errMsg += "Position: " + args.charPosition + " \n";
}
errMsg += "MethodName: " + args.methodName + " \n";
}

throw new Error(errMsg);
}
</script>
</
head>
<
body>
<
form id="form1" runat="server" style="height:100%">
<
div id="silverlightControlHost">
<
object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
<
param name="source" value="ClientBin/silverlight.net.xap"/>
<
param name="onError" value="onSilverlightError" />
<
param name="background" value="white" />
<
param name="minRuntimeVersion" value="3.0.40624.0" />
<
param name="autoUpgrade" value="true" />
<
param name="initParams" value='ip=<%=(Request.ServerVariables["REMOTE_ADDR"])%>,agent=<%=(Request.ServerVariables["HTTP_USER_AGENT"])%>' />
<
a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0" style="text-decoration:none">
<
img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>
</
a>
</
object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>
</
form>
</
body>
</
html>



Here is the Silverlight Application code (App.xaml.cs) :



using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace silverlight.net
{
public partial class App : Application
{

public App()
{
this.Startup += this.Application_Startup;
this.Exit += this.Application_Exit;
this.UnhandledException += this.Application_UnhandledException;

InitializeComponent();
}

private void Application_Startup(object sender, StartupEventArgs e)
{
if(e.InitParams != null)
{
foreach(var item in e.InitParams)
{
this.Resources.Add(item.Key, item.Value);
}
}

this.RootVisual = new UserIPAddress();
}

private void Application_Exit(object sender, EventArgs e)
{

}
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
// If the app is running outside of the debugger then report the exception using
// the browser's exception mechanism. On IE this will display it a yellow alert
// icon in the status bar and Firefox will display a script error.
if (!System.Diagnostics.Debugger.IsAttached)
{

// NOTE: This will allow the application to continue running after an exception has been thrown
// but not handled.
// For production applications this error handling should be replaced with something that will
// report the error to the website and stop the application.
e.Handled = true;
Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); });
}
}
private void ReportErrorToDOM(ApplicationUnhandledExceptionEventArgs e)
{
try
{
string errorMsg = e.ExceptionObject.Message + e.ExceptionObject.StackTrace;
errorMsg = errorMsg.Replace('"', '\'').Replace("\r\n", @"\n");

System.Windows.Browser.HtmlPage.Window.Eval("throw new Error(\"Unhandled Error in Silverlight Application " + errorMsg + "\");");
}
catch (Exception)
{
}
}
}
}



Here is the Page XAML (UserIPAddress.xaml):



<navigation:Page x:Class="silverlight.net.UserIPAddress" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
d:DesignWidth="640" d:DesignHeight="480"
Title="UserIPAddress Page">
<
Grid x:Name="LayoutRoot">
<
StackPanel>
<
TextBlock x:Name="IpAddress"></TextBlock>
<
TextBlock x:Name="UserAgent"></TextBlock>
</
StackPanel>
</
Grid>
</
navigation:Page>



Here is the Silverlight Page codebehind  (UserIPAddress.xaml.cs):



using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;

namespace silverlight.net
{
public partial class UserIPAddress : Page
{
public System.String ClinetIP;
public UserIPAddress()
{
InitializeComponent();

if (App.Current.Resources.Contains("ip"))
IpAddress.Text = (System.String)App.Current.Resources["ip"];

if (App.Current.Resources.Contains("agent"))
UserAgent.Text = (System.String)App.Current.Resources["agent"];
}
}
}



I hope this helps!



Tzanimir

Thursday 13 August 2009

Silverlight TreeView – Binding ItemContainerStyle properties to DataContext

If you are doing work with TreeView in Silverlight you most likely already know that you cannot natively do Binding for ItemContainerStyle properties like IsSelected or Visibility. Recent question in silverlight.net forum, at first confused me – this is no problem in WPF, and then made me spend couple of hours finding a “workaround”. So here is one way to do this in Silverlight (in WPF this is not needed as native Bidning is supported)

The workaround is based around the ContainerFromItem method of the ItemContainerGenerator for the TreeView (or any other ItemsControl).  What the example below does is to create a test data Structure that consists of DataItem objects and apply it to the DataContext of the TreeView trough a object called DataContainer.

The “Binding” is fired trough the Setter method of the Binded Property (IsVisible or IsExpanded) in the data structure. What the setter needs to know is a reference to the ItemsControl (the TreeView in this case) in order to use the ContainerFromItem to get reference to the actual container for the Item. This is information can be passed to the DataItem in multiple ways, but in the example this is done trough a Method of the DataContainer that updates all DataItems with the necessary reference to the TreeView.

The handling of the LayoutUpdated event handler of the TreeView is used for Initial setting of the properties as passed.

The rest is pretty simple. Hese is fully working example- the Xaml:

<navigation:Page x:Class="silverlight.net.TreeViewBinding" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
xmlns:Controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
xmlns:Windows="clr-namespace:System.Windows;assembly=System.Windows.Controls"
d:DesignWidth="640" d:DesignHeight="480"
Title="TreeViewBinding Page">
<
UserControl.Resources>
<
Windows:HierarchicalDataTemplate x:Key="ItemDataTemplate" ItemsSource="{Binding Children}">
<
TextBlock Text="{Binding Name}"></TextBlock>
</
Windows:HierarchicalDataTemplate>
</
UserControl.Resources>
<
Grid x:Name="LayoutRoot">
<
StackPanel>
<
Button Content="Togle Item 2 Visibility" Click="Button_Toggle_Visibility" HorizontalAlignment="Left" VerticalAlignment="Top"></Button>
<
Button Content="Togle Item 2 IsExpanded" Click="Button_Toggle_IsExpanded" HorizontalAlignment="Left" VerticalAlignment="Top"></Button>
<
Controls:TreeView x:Name="TestTreeView" ItemTemplate="{StaticResource ItemDataTemplate}" ItemsSource="{Binding Children}">
</
Controls:TreeView>
</
StackPanel>
</
Grid>
</
navigation:Page>


And here is the Code behind:



using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;

namespace silverlight.net
{
public partial class TreeViewBinding : Page
{
DataContainer dataContainer = new DataContainer();

public TreeViewBinding()
{
InitializeComponent();
// Create some test Data
DataItem item1 = new DataItem() { Name = "Test1" };
DataItem item2 = new DataItem() { Name = "Test2" };
DataItem item2_1 = new DataItem() { Name = "Test2.1" };
DataItem item2_2 = new DataItem() { Name = "Test2.2" };
item2.Children.Add(item2_1);
item2.Children.Add(item2_2);

DataItem item3 = new DataItem() { Name = "Test3" };

dataContainer.Children.Add(item1);
dataContainer.Children.Add(item2);
dataContainer.Children.Add(item3);

dataContainer.ItemsControl = TestTreeView;

TestTreeView.DataContext = dataContainer;
TestTreeView.LayoutUpdated += new EventHandler(treeMatrix_LayoutUpdated);
}

void treeMatrix_LayoutUpdated(object sender, EventArgs e)
{
dataContainer.UpdateAdditionalBindings();
}


private void Button_Toggle_Visibility(object sender, RoutedEventArgs e)
{
if (dataContainer.Children[1].IsVisible)
dataContainer.Children[1].IsVisible = false;
else
dataContainer.Children[1].IsVisible = true;
}


private void Button_Toggle_IsExpanded(object sender, RoutedEventArgs e)
{
if (dataContainer.Children[1].IsExpanded)
dataContainer.Children[1].IsExpanded = false;
else
dataContainer.Children[1].IsExpanded = true;
}
}
public class DataContainer
{
public System.Boolean UpdateLayout = true;
public List<DataItem> Children {get; set;}

// Reference to the Items control
private ItemsControl _ItemsControl;
public ItemsControl ItemsControl
{
get { return _ItemsControl; }
set
{
_ItemsControl = value;

// Propagade the Items control to the children
foreach (DataItem data_item in Children)
{
data_item.ItemsControl = value;
}
}
}

public void UpdateAdditionalBindings()
{
foreach (DataItem item in Children)
item.UpdateAdditionalBindings();
}

public DataContainer()
{
Children = new List<DataItem>();
}
}

public class DataItem
{
// Reference to the Items control
private ItemsControl _ItemsControl;
public ItemsControl ItemsControl
{
get { return _ItemsControl; }
set
{
_ItemsControl = value;

// Propagade the Items control to the children
foreach (DataItem data_item in Children)
{
data_item.ItemsControl = value;
}
}
}

public List<DataItem> Children {get; set;}

public override string ToString()
{
return Name;
}

public System.String Name { get; set; }

private System.Boolean _IsVisible = true;
public System.Boolean IsVisible
{
get { return _IsVisible; }
set
{
if (_IsVisible != value)
UpdateVisibility(value);

_IsVisible = value;
}
}

private System.Boolean _IsExpanded = true;
public System.Boolean IsExpanded
{
get { return _IsExpanded; }
set
{
if (_IsExpanded != value)
UpdateIsExpanded(value);

_IsExpanded = value;
}
}

public void UpdateAdditionalBindings()
{
// Here update all properties
this.UpdateVisibility(_IsVisible);
this.UpdateIsExpanded(_IsExpanded);

foreach (DataItem dataItem in Children)
dataItem.UpdateAdditionalBindings();
}

private void UpdateVisibility(System.Boolean isVisible)
{
if (ItemsControl == null) return;

UIElement container = (UIElement)ItemsControl.ItemContainerGenerator.ContainerFromItem(this);
if (container != null)
{
if (isVisible)
container.SetValue(UIElement.VisibilityProperty, Visibility.Visible);
else
container.SetValue(UIElement.VisibilityProperty, Visibility.Collapsed);
}
}
private void UpdateIsExpanded(System.Boolean isExpanded)
{
if (ItemsControl == null) return;

TreeViewItem container = (TreeViewItem)ItemsControl.ItemContainerGenerator.ContainerFromItem(this);
if (container != null)
{
container.SetValue(TreeViewItem.IsExpandedProperty, isExpanded);
}
}

public DataItem()
{
Children = new List<DataItem>();
}
}
}




I hope this helps you !



Tzanimir

Friday 7 August 2009

WPF TreeView – Different DataTemplate for Different Data Types

Have you wondered how you can show or edit different types of data using different DataTemplates in a TreeView? It is actually pretty easy – here is a way to do it:

The key is simple DataType="{x:Type System:String}" attribute for the DataTemplate which identifies for which Type will the DataTemplate be used. Here the System: is just a namespace import and String is the type:

xmlns:System="clr-namespace:System;assembly=mscorlib"
Here is the complete Example that shows data of types String, Int32 and Double in different colors and a note of the type before the value:


<Window x:Class="Blog.TreeViewExample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation%22
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml%22
xmlns:System="clr-namespace:System;assembly=mscorlib"
Title="TreeViewTest" Height="300" Width="300">

<Grid>
<TreeView x:Name="TreeView" ItemsSource="{Binding}">
<TreeView.Resources>
<DataTemplate DataType="{x:Type System:String}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="(System.String): "></TextBlock>
<TextBlock Foreground="Blue" FontWeight="Bold" Text="{Binding}" />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type System:Double}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="(System.Double): "></TextBlock>
<TextBlock Foreground="Green" FontWeight="Bold" Text="{Binding}" />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type System:Int32}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="(System.Int32): "></TextBlock>
<TextBlock Foreground="Red" FontWeight="Bold" Text="{Binding}" />
</StackPanel>
</DataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
</Window>


And the Code behind:


namespace Blog
{
/// <summary>
///
Interaction logic for TreeViewTest.xaml
/// </summary>
public partial class TreeViewExample : Window
{
public TreeViewExample()
{
InitializeComponent();

// Some sample data with different Types
TreeView.DataContext = new List<System.Object> {
(System.String) "Item1",
(System.Int32) 1,
(System.Double) 2.0 };
}
}
}
Enjoy ! Tzanimir