How to use HttpWebRequest to send POST request to another web server in Silverlight?

by Naveen 10. March 2010 10:14

Download Sample Projects (114.64 kb)

Quite some time back I wrote about How to use HttpWebRequest to send POST request to another web server in ASP.Net applications. Now that a lot of silverlight applications are being developed, we have similar need to post data from silverlight applications. The concept is exactly the same that I used in ASP.Net. But there is little difference. Silverlight does not allow blocking synchronous requests. All web requests are asynchronous. That means we have little bit more book keeping to do and manage the thread contexts etc. to make sure that then requests complete and we need to do any UI work in call back methods, we stay in correct thread context.

To keep example simple, I am going to post two values to destination URL using POST method. In the attached project, on Slots.xaml page, I have added a simple button Submit Data. And in the event handler of this button, I initiated request to submit data to Default page of sample web application. The event handler for the click looks as below.


private void SubmitData_Click(object sender, RoutedEventArgs e)
{
 // Prepare web request...
 HttpWebRequest myRequest =
 (HttpWebRequest)WebRequest.Create("http://localhost/SilverGridWeb/Default.aspx");
 myRequest.Method = "POST";
 myRequest.ContentType = "application/x-www-form-urlencoded";
 myRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), myRequest);
}

This code is pretty much same as what I had in ASP.Net application. There is one difference. Instead of calling GetRequestStream method, you will need to call BeginGetRequestStream. This will initiate an asynchronous request. There are two parameters that are passed to this method. First is the callback method that needs to be called when this method completes. Second parameter is any object that you want to pass to callback method. So here I have passed my HttpWebRequest object itself.

Now lets look at what is this callback method GetRequestStreamCallback. I copied the function from Microsoft documentation itself and made some changes to fit my needs.


private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
 HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
 System.IO.Stream postStream = request.EndGetRequestStream(asynchronousResult);
 string strId = "My Id";
 string strName = "My Name";
 string postData = "userid=" + strId;
 postData += ("&username=" + strName);
 byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(postData);
 // Write to the request stream.
 postStream.Write(byteArray, 0, postData.Length);
 postStream.Close();
 // Start the asynchronous operation to get the response
 request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}

You can see that in callback method, I grabbed the request object that was passed as state to the method call. Then I constructed data that I need to pass with the request that needed to be sent as POST. And then made another async call BeginGetResponse to submit the data and get the response.

Now lets look at what is this callback method for response.


private void GetResponseCallback(IAsyncResult asynchronousResult)
{
 HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
 HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
 Stream streamResponse = response.GetResponseStream();
 StreamReader streamRead = new StreamReader(streamResponse);
 string responseString = streamRead.ReadToEnd();
 // Close the stream object
 streamResponse.Close();
 streamRead.Close();
 // Release the HttpWebResponse
 response.Close();
 Action<string> act = new Action<string>(DisplayResponse);
 this.Dispatcher.BeginInvoke(act, responseString);
}

void DisplayResponse(string msg)
{
 GainersText.Text = msg;
}

Again I passed original HttpWebRequest object to the call method as state. In the call back method, you can grab the request object and then call EndGetResponse to get the resonse stream.

Thread Context and Invalid cross-thread access error

You will notice that in GetResponseCallback method I have called BeginInvoke method on Dispatcher thread. This is very important if you are planning on doing any UI manipulation in the call back methods. The call back methods are invoked on a thread that are separate from the UI thread that initiated the request. So if you try to access any UI element in this callback you will get the following exception thrown.


An unhandled exception ('Unhandled Error in Silverlight Application 
Code: 4004    
Category: ManagedRuntimeError       
Message: System.UnauthorizedAccessException: Invalid cross-thread access.
   at MS.Internal.XcpImports.CheckThread()
   at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value, 
   Boolean allowReadOnlySet, Boolean isSetByStyle, Boolean isSetByBuiltInStyle,
   PropertyInvalidationReason reason)
   at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value)
   at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
   at System.Windows.Controls.TextBlock.set_Text(String value)
   at SilverGrid.Views.Stocks.GetResponseCallback(IAsyncResult asynchronousResult)
   at System.Net.Browser.BrowserHttpWebRequest.<>c__DisplayClassd.
    <InvokeGetResponseCallback>b__b(Object state2)
   at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, 
   ContextCallback callback, Object state)
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal
   (_ThreadPoolWaitCallback tpWaitCallBack)
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)     
') occurred in iexplore.exe [7532].

Therefore it is important that from the callback method, you invoke an action request on Dispatcher thread of UI.

Views: 126

Tags:

Silverlight

Silverlight Cross Domain Web Service Access Error - This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place

by Naveen 9. March 2010 08:37

Here is some error that most of Silverlight developers run into at some point.


An error occurred while trying to make a request to URI 
'http://nave-pc/SilverGridWeb/GridDataService.asmx'.
This could be due to attempting to access a service in a cross-domain way 
without a proper cross-domain policy in place, or a policy that is unsuitable 
for SOAP services. You may need to contact the owner of the service to publish 
a cross-domain policy file and to ensure it allows SOAP-related 
HTTP headers to be sent. This error may also be caused by using internal types 
in the web service proxy without using the InternalsVisibleToAttribute attribute. 
Please see the inner exception for more details.

I had developed cross-domain access web services for Silverlight in the past and all work like a charm. This morning I ran into this issue again while developing a new web service for a new Silverlight application. I knew that I needed to add CrossDomain.xml or ClientAccessPolicy.xml at root of my web application. So I copied those files from existing application to this new one. To my surprise it did not resolve the issue. I tried all kind of tricks and options but nothing seemed to help. Finally I decided to look at Silverlight documentation and see if there is anything new that has been done for Silverlight 3. Last time I did this was for a Silverlight 2.0 application. I could not find anything different in the description of what needed to be done. But then there was something in the sample XML file content for these files that caught my eye and looked different that what I had.


<allow-from http-request-headers="SOAPAction" >

Notice the underlined section. Previously the value in the allowed headers used to be *. Well, that does not seem to work any more. So I replaced it and everything worked fine.

There are some other important points I am going to discuss in this post. A lot of users do not seem to be clear where these cross domain policy files should be placed.

Location of CrossDomain.xml and ClientAccessPolicy.xml

As the documentation states, these should be placed at the root of the application. Although the statement is very clear but it causes lot of confusion about what is root? There are two ways you create a site in IIS, Virtual Directory and Web Application. So if you have a web site foo.com created as a web site in IIS, then the folder containing the content of this site is root of the application. So your policy files go in that folder. If you have created a virtual directory Bar under this web site where your web service is hosted, then the root of the site is still foo.com and not foo.com/bar. To verify it, open IIS log of your application and look for entries for Crossdomain.xml and ClientAccessPolicy.xml. From those entries you can figure out where those files should be located. If the caller is not finding those files, then you should 404 errors in your log file. For example here are entries from my log file.


1.17.30.170 GET /clientaccesspolicy.xml - 80 - 1.17.30.162  404 0 2 1
1.17.30.170 GET /crossdomain.xml - 80 - 1.17.30.162 404 0 2 1

This is very important. If you are hosting your web service in a web application that is created as a virtual directory in Default Web Site then you need to copy these files in wwwroot folder or whatver folder is configured to be default folder for your IIS installation. Copying policy files in your virtual directory is not going to help. You can also verify the location by looking at traffic in fiddler for your web service access.

Content for CrossDomain.xml and ClientAccessPolicy.xml

I have copied the content of these two files below. These files work for me on my my servers for cross domain access from silverlight.

ClientAccessPolicy.xml


<?xml version="1.0" encoding="utf-8"?>
<access-policy>
	<cross-domain-access>
		<policy>
			<allow-from http-request-headers="SOAPAction ">
				<domain uri="*"/>
			</allow-from>
			<grant-to>
				<resource path="/" include-subpaths="true"/>
			</grant-to>
		</policy>
	</cross-domain-access>
</access-policy>

CrossDomain.xml


<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
	<allow-http-request-headers-from domain="*" headers="SOAPAction,Content-Type"/>
</cross-domain-policy>

Views: 73

Tags: , ,

Silverlight | WCF | Web Service

How to display custom tool tips in Silverlight Charts?

by Naveen 3. March 2010 11:49
custom tool tip in silverlight charts

Download Sample Projects (28.22 kb)

In my previous post, How to set silverlight column chart style programatically", I discussed one of the customizations of chart styles. In this post I will discuss one more customization of Silverlight charts rendering. This is about customizing display of Tooltip display on charts. If you look at default tool tip display, they are limited to displaying some combination of Independent and Dependent value. In some cases, that information is sufficient. But you may have cases where you want your tool tips to be verbose to convey more information about the data point that was used to render that point or column etc.

Template is the key

First and foremost concept that you will need to understand is how a chart actually gets rendered. Who decided the layout of various components of a chart display. Like any other Silverlight control, its the control template that defines how to chart is going to be rendered. So to customize the dispplay of Silverlight control, you can create a new template or take the default template and make modifications to it to come up with your own display scheme. Now you are asking from where can you get the default template for various chart types. The answer to it is Silverlight Toolkit source code. If you look in Charting/DataPoint folder of Controls.DataVisualization.Toolkit project, you will find template files for all chart types.

Customize Tooltip For Chart

Let us get started. For this discussion I picked Column type chart. Here are the steps that I followed to create a new template file for my column charts.

  • Add a new resource dictionary file in your project. In sample project I added ColumnChartStyle.xaml file under Assets folder.
  • Open ColumnDataPoint.xaml file from DataPoint folder from tool kit source. Copy the content of this file into your resource file.
  • Make sure that you change the build action of your resource file to Resource from Page
  • Assign a key to your style as shown below. You can pick any unique name. You are going to use the key when we apply this new template and style to our column charts.
    
    <Style TargetType="charting:ColumnDataPoint" x:Key="ByteBlocksColumns">
    
    
  • Open the XAML file where you have added chart that you want to display. In the sample project, it is in Home.xaml. And then assign DataPointStyle property to point to the static resource that we created from default implementation of ColumnDataPoint. And make sure that you use the key name that you used in the resource file. Following snippet shows how I did it in sample project.

    
    <chartingToolkit:Chart Title="Fruit Supply and Demand" 
       x:Name="FruitChart" 
       Width="500" 
       Height="350">
     <chartingToolkit:Chart.Series>
      <chartingToolkit:ColumnSeries
    		DataPointStyle="{StaticResource ByteBlocksColumns}"
            Title="Fruit Supply"
            IndependentValueBinding="{Binding Name}"
            DependentValueBinding="{Binding Supply}"/>
      </chartingToolkit:Chart.Series>
    </chartingToolkit:Chart>
    
    

Now you should be able to compile and run your project. We have not done any customization of tool tip yet. At this point you should be able to run the project with default template.

TooltipService and Tooltip

If you look near bottom of ColumnChartStyle.xaml file, you will find following snippet of code.


<ToolTipService.ToolTip>
 <ContentControl Content="{TemplateBinding FormattedDependentValue}"/>
</ToolTipService.ToolTip>

This is default implementation of how and what is displayed in tool tip. So you can see that by default only DependentValue is displayed. So this is the place where you will need to make changes to customize the display of tooltip for chart. If you are only interested in making some minor changes like adding some static text or adding display of dependent value as well, you can make a change as below.


<ToolTipService.ToolTip>
 <StackPanel Orientation="Horizonal">
 <ContentControl Content="{TemplateBinding FormattedDependentValue}"/>
 <TextBlock Text="-" />
  <ContentControl Content="{TemplateBinding FormattedIndependentValue}"/>
 </StackPanel Orientation="Horizonal">
</ToolTipService.ToolTip>

Customizing Tooltip Display at run time

In the sample project, I have implemented a use case where I want to create tool tip display at run time. What this means is that content of tool tip is being constructed based on some input from the existing data that is bound to that column. So in the template I am going to make some changes as shown below.


<ToolTipService.ToolTip>
<StackPanel Orientation="Horizontal">
<ContentControl Content="{Binding Id, Converter={StaticResource FruitConverter}}"/>
</StackPanel>
</ToolTipService.ToolTip>

In the snippet above you will see use of two things. One is that I am binding the content to the actual data object that was used to render that point. Second is use of converter. I am passing "Id" of the object as parameter to the converter. And in the converter I do some mock query to get more data. Following code shows how I constructed text of tool tip.


public class FruitSupplyToolTipConverter : IValueConverter
{
 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
 {
  return GetToolTip(int.Parse(value.ToString()));
 }

 public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
 {
  return value;
 }

 object GetToolTip(int id)
 {
  var supply = MockData.FruitSupply.GetSupply();
  var query = from item in supply where item.Id == id select item;
  var items = query.ToList();
  if (items.Count == 0)
  {
   return string.Empty;
  }
  return CreateToolTip(items[0]);
 }

 object CreateToolTip(FruitSupply supply)
 {
  var panel = new StackPanel();
  panel.Orientation = Orientation.Vertical;
  var tipTextBlock = new TextBlock();
  tipTextBlock.Inlines.Add(new Run { Text = supply.Name });
  tipTextBlock.Inlines.Add(new LineBreak());
  tipTextBlock.Inlines.Add(new Run { Text = string.Format("Supply: {0}", supply.Supply)});
  tipTextBlock.Inlines.Add(new LineBreak());
  panel.Children.Add(tipTextBlock);
  var hlink = new HyperlinkButton();
  hlink.Content = "For more informattion Goto http://www.ByteBlocks.com";
  hlink.NavigateUri = new Uri("http://www.byteblocks.com");
  panel.Children.Add(hlink);
  return panel;
  }
}

You could argue that instead of going to the extent of using converter to build a tool tip text, I could have added another property to data object that contains the text and then bind tool tip to that property. That would have worked perfectly as well. But for demonstrating how you can construct tool tip text based on some other pieces of data or if tool tip content changes rapidly with time as well, then you need to access it at run time.

I hope this should give you good starting point to go nuts on more nifty tool tips.

Views: 157

Tags: , ,

Charting | Silverlight

Temporary Internet Files Location In Windows 7

by Naveen 25. February 2010 07:06

With Windows 7 a lot of things have changed as far as location of certain folders go. In my previous post Location Of Documents and Settings Folder in Windows 7 I talked about how you can access your Documents And Settings Folder on Windows 7. Other day I was asked where has Temporary Internet Files folders have been moved.

There is an obvious answer to this question but lot of times we just forget about it. If you bring up Options dialog box from Tools menu or tool bar button, you can see location of this folder by clicking on Settings button. Following screen shots two steps that you need to follow to find location of your Temporary Internet Files folder location.

  • IE options
  • temporary innternet file folder

As a quick reference you will find Temporary Internet Files folder at following location.

C:\Users\{User Account}\AppData\Local\Microsoft\Windows\Temporary Internet Files

Views: 166

Tags: ,

IE | Windows 7

How to add paging to DataGrid in Silverlight

by Naveen 24. February 2010 10:23

Download Sample Project (367.89 kb)

paging in silverlight datagrid

In one of my previous posts How to use DataGrid in Silverlight I showed a very simple usage where data grid was bound to a list of products. Now let us take one more step in customizing use of this data grid. When I executed my method to get list of products from AdventureWorks database, it returned me about 1000 records. And then datagrid was bound to that list, i got a huge page with grid showing all the records. I am sure at this point you are looking for way to add some kind of paging to your data grid so that user can navigate the list easily.

Silverlight has a control named DataPager that comes in very handy to add paging functionality to any control that you use to display lists. From the name is it obvious that this control is a pager. Following XAML shows how I added paging functionality to my datagrid.


<StackPanel x:Name="ContentStackPanel" Orientation="Vertical">
 <TextBlock x:Name="HeaderText" Style="{StaticResource HeaderTextStyle}" 
     Text="Products"/>
  <data:DataPager x:Name="ProductsPager" 
    PageSize="10" 
    DisplayMode="Numeric" 
    AutoEllipsis="True" 
    HorizontalAlignment="Left" />
  <data:DataGrid x:Name="ProductsGrid">
   <data:DataGrid.Columns>
   <data:DataGridTemplateColumn>
   <data:DataGridTemplateColumn.CellTemplate>
   <DataTemplate>
   <StackPanel>
   <Button x:Name="UpdateButton" Content="Update" 
     Click="UpdateButton_Click"></Button>
   </StackPanel>
   </DataTemplate>
   </data:DataGridTemplateColumn.CellTemplate>
   </data:DataGridTemplateColumn>
   </data:DataGrid.Columns>
   </data:DataGrid>
</StackPanel>

You can read more about different ways to customize the display of datapager from the documentation. For this discussion you can see that I have set PageSize, DisplayMode, AutoEipsis and HorizontalAlignment properties of pager and the screen shot shows how it looks. I will talk more about customization of DataPager in detail in next post. For now I just want to keep it to simple use.

PageViewCollection

This is the collection object that drives the functionality for DataPager. In general you need a collection that implements IPagedViewCollection interface. No, you do not have to do any more implementation to get DataPager to work. We already have list of products obtained from previous web service call. You can simply wrap that list into PagedViewCollection object and set it as Source for DataPager object. And then set the source for DataGrid as this PagedViewCollection object and we are all set to go. Following code shows simple change I made in code from previous sample project.


void GetProductsCompleted(object sender, GetProductsCompletedEventArgs e)
{
 _products = e.Result;
 if (null != _products)
 {
  _pagedProductsView = new PagedCollectionView(_products);
  ProductsPager.Source = _pagedProductsView;
  ProductsGrid.ItemsSource = _pagedProductsView;
 }
}

Add References

PagedViewCollection is defined in System.Windows.Data assembly. So you will need to add reference to this assembly in your Silverlight project and then add using directive for the namespace in your source code to refer to the classes in this namespace and assembly.

Adding Paging to DataGrid in Silverlight is as easy as that.

Views: 207

Tags: ,

DataGrid | Silverlight

How to add buttons to Silverlight DataGrid?

by Naveen 11. February 2010 15:36

Download Sample Project

In the previous post How to use Silverlight DataGrid I discussed simple use of DataGrid in Silverlight application. Now it is time to start putting together implementation that we have from day to day to applications. One of the tasks that you may come across is that you need to add buttons to each row in the DataGrid and then handle click events for those buttons. In the previous post I mentioned use of DataGridTemplateColumn to provide custom rendering of columns in the grid. So to add button(s) to your column, you will use the template column and then provide Button control to add them to each row. Following snippet shows how it looks like in my sample application.


<data:DataGrid x:Name="ProductsGrid">
 <data:DataGrid.Columns>
  <data:DataGridTemplateColumn>
  <data:DataGridTemplateColumn.CellTemplate>
   <DataTemplate>
    <StackPanel>
     <Button x:Name="UpdateButton" Content="Update" 
        Click="UpdateButton_Click"></Button>
    </StackPanel>
   </DataTemplate>
  </data:DataGridTemplateColumn.CellTemplate>
 </data:DataGridTemplateColumn>
 </data:DataGrid.Columns>
</data:DataGrid>

Handling Click Event For Button In DataGrid

As you can see from the XAML above, I just added handling of Click event on Button control. And in the codebehind provided implementation for it.


private void UpdateButton_Click(object sender, RoutedEventArgs e)
{
 var ctl = e.OriginalSource as Button;
 if (null != ctl)
 {
  var product = ctl.DataContext as Product;
  if (null != product)
  {
   var msg = string.Format("{0}, {1}, {2}", 
      product.ProductID, product.Name, product.ListPrice);
   MessageBox.Show(msg);
  }
 }
}

Accessing Data Associated With Row In DataGrid

When user clicks on the button in datagrid row, the method gets called. Next question you have is how do you access the data associated with the row on which button was clicked. It is very straight forward. When DataGrid rendering takes place, each control in the row is bound to DataContext. This DataContext is the data that was used to render that row. So you simple look at DataContext property of Button control that raised the event and got the actual data object used for that row.

I think this should give you a good starting point on how to add buttons or some other controls in DataGrid rows and how to access data for them as well. In next post I will discuss more of customization of Silverlight DataGrid.

Views: 386

Tags: ,

DataGrid | Silverlight

How to use DataGrid in Silverlight

by Naveen 5. February 2010 06:58
DataGrid is one of the most important control when it comes to displaying tabular kind of data. We all implement rendering of such data in some of table format. Developers who has been using ASP.Net are very familiar with controls like DataGrid and GridView. Good news is that there is equivalent DataGrid control for Silverlight as well. And for most part it is used the same way as you do in ASP.Net but with different syntax and different way of customizing display of it. In this post I am going to show a very plain and simple use of DataGrid control in Silverlight and then in subsequent posts I will build on top of this post to show some more advanced uses of DataGrid control.

Silverlight Tool Kit

You may already know this and already has it on your development machine, but I will mention it for sake of completness. You are going to need Silverlight Toolkit to use DataGrid. Yes, the control is not part of core Silverlight. Microsoft has developed it as part of the tool kit that has lot of usefull controls. You can read more about this tool kit and controls on the site. For now, down the toolkit and install it on your machine.

Reference assemblies

In your Silverlight project, you will need to add reference to System.Windows.Controls.Data assembly. This is the assembly where DataGrid control is defined. Now you can include DataGrid control on your XAML file. If you tried to add mark up like below on your page, you are going to get error telling you that DataGrid is not recoganized.


<DataGrid x:Name="MyGrid" />

You have to treat DataGrid control like a UserControl in ASP.Net where you have to specify a tag prefix and assembly on top of your page to indicate use of that control. In Silverllight you do this my including xml namespace tag for that silverlight control. In my case I have the following xmlns entry on my XAML file.


xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"

This tells the application that I am going to use prefix data for the controls that are present in assembly System.Windows.Controls.Data. Based on this you can now add the following like of mark up on XAML file to include DataGrid on your page.


<data:DataGrid 
  x:Name="CommentsGrid" 
  Height="300" 
  AutoGenerateColumns="True" 
  IsReadOnly="True">
</data:Grid>

Attach To Data Source

Now that we have included DataGrid control on the page, we need to attach it to some data source to show some results. Very much like ASP.Net, you will attach an enumeration to this control. The difference is that here it is done through property name ItemSource. Following line of code shows how it is done for silverlight DataGrid control.


List<Comment> unmoderatedComments = new List<Comment>();

void BindGrid()
{
 CommentsGrid.ItemsSource = unmoderatedComments;
}

As you can see that DataGrid is bound to a List of Comment objects. So far so good, very much like your ASP.Net DataGrid or GridView.

Columns to Display

In the mark of DataGrid above, I have explcitly set AutoGenerateColumn property to true. This actually is default value. What this means is that when DataGrid is bound to the collection, it will generate column for each data field or property for the objects in the collection and display them. Thsi is same behavior you see in ASP.Net data grid.

Explcitly specifying Columns

When you are dealing with some real application most of the time you control the columns you want to display and how you want to display them. Silverlight DataGrid does allow you to do so. Fisrt, you will set AutoGenerateColumns property to false. Following mark up shows how you will specify the columns that you want to display.


<data:DataGrid x:Name="CommentsGrid" Height="300" 
  AutoGenerateColumns="False" IsReadOnly="True">
 <data:DataGrid.CellStyle>
  <Style TargetType="data:DataGridCell">
  <Setter Property="VerticalAlignment" Value="Top"></Setter>
  </Style>
 </data:DataGrid.CellStyle>
 <data:DataGrid.Columns>
  <data:DataGridTextColumn Header="Comment Date" 
    Binding="{Binding CommentDate}"></data:DataGridTextColumn>
  <data:DataGridTextColumn Header="Comment Text" Binding="{Binding Text}">
  <data:DataGridTextColumn.ElementStyle>
  <Style TargetType="TextBlock">
   <Setter Property="TextWrapping" Value="Wrap"/>
  </Style>
  </data:DataGridTextColumn.ElementStyle>
 </data:DataGridTextColumn>
 <data:DataGridTemplateColumn>
  <data:DataGridTemplateColumn.CellTemplate>
   <DataTemplate>
    <StackPanel Orientation="Horizontal">
     <Button x:Name="ApprovedButton" Content="Approved" 
       Click="ApprovedButton_Click" Height="30" Margin="3"></Button>
     <Button x:Name="DeleteButton" Content="Delete" 
        Click="DeleteButton_Click" Height="30" Margin="3"></Button>
     <Button x:Name="SpamButton" Content="Mark Spam" 
       Click="SpamButton_Click" Height="30" Margin="3"></Button>
   </StackPanel>
   </DataTemplate>
  </data:DataGridTemplateColumn.CellTemplate>
 </data:DataGridTemplateColumn>
 </data:DataGrid.Columns>
</data:DataGrid>

You will need to add Columns section under your DataGrid control definition and then specify each column that you would want to display. And to bind the column to particular property or field, you will use Binding property. For this post I am going to keep the dicussion to simple binding of the column to property of the object. I will discuss more advanced use in subsequent posts. You can see it is very similar to how you are used to doing things in ASP.Net.

And to accomodate more customized view of the column, you will use DataGridTemplateColumn where you can layout the template of the view of that column. This is also similar to template column in ASP.Net.

More...

For this post I am going to leave this discussion to this simple display of data. I will be discussing more about use of Silverlight DataGrid in subsequent posts. This post should get you started with use of it now.

Views: 448

Tags: ,

DataGrid | Silverlight

How to customize Privacy Statement and Terms and Conditions pages in DNN

by Naveen 1. February 2010 06:53

While developing a web site for one of my clients, I needed to put custom Privacy and Terms & User page. After digging around I found that the text that gets displayed on these pages from default implementation of Privacy and Terms control is saved as resource in resources. When I went to look at the page where you enter the text I got ticked off. There was a tiny square text box where you needed to put the text. Yes, I know I could create the HTML for those pages in some nifty HTML editor like Expression or Dreamweaver and then paste it there. That worked fine but then there was another issue. I needed to show a common module on all pages. This default implementation did not do it for me even though I had marked a module to show on all pages of the site.

If you hover on Privacy and Terms of user link, you will see that it is pointing to pages Privacy.aspx and Terms.aspx. Then it clicked to me that if I add new pages into the system with names Privacy and Terms it may override the default implementation.

I created two new pages in the system with the names Privacy and Terms and it worked. Since I did not want these pages to be showing as menu options in top or other navigation bars, so make sure that when you add these new pages you check off the option of not including them in menu.

Views: 481

Tags: ,

DotNetNuke

WCF Error - The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state

by Naveen 15. January 2010 11:37

While working on a WCF service, I ran into the following error.


The communication object, System.ServiceModel.Channels.ServiceChannel,
cannot be used for communication because it is in the Faulted state.

This occurred when called Close method on instance of my WCF service client object. For a moment it took me by surprise. The code has been working fine and I was doing the right thing of closing connection to my WCF service after I was done using it. When I looked at the stack trace, I realized that it got thrown from a finally block of a method where I was calling a method on my WCF object. And before that there was an exception thrown. After further investigation it turned out that my WCF service was not running. So when I called method on the object, I got EndpointNotFoundException exception thrown when method was called. And in the same exception handling block I tried to call Close on client object. Since the client was already in bad state so next exception was thrown. So as a best practice, before you call Close method on your service object, check if its in Open state or not. This is exactly like a database connection object where you can check if its in open state or not. The following code snippet shows the change that I made to check for state of the WCF client object.


if (_serviceClient.State == CommunicationState.Opened)
{
 _serviceClient.Close();
}

Views: 985

Tags:

WCF

How to hide navigation controls on Bing Map Silverlight control

by Naveen 7. January 2010 17:25

Default rendering of Bing Map Silverlight Control displays few of the in-built controls like Copyright, Scale, Navigation, Logo etc. If you are not interested in displaying any of these controls, you can simply hide it by setting their visibility. Following code snippet shows how to hide these navigation controls.


void SetMapForgroundMembers()
{
 UserLocationsMap.NavigationVisibility = System.Windows.Visibility.Collapsed;
 UserLocationsMap.LogoVisibility = Visibility.Collapsed;
 UserLocationsMap.CopyrightVisibility = System.Windows.Visibility.Collapsed;
 UserLocationsMap.ScaleVisibility = System.Windows.Visibility.Collapsed;
}		}

Views: 524

Tags: ,

Silverlight

Unable to open the physical file. Operating system error 5: "5(Access is denied.)". (Microsoft SQL Server, Error: 5120)

by Naveen 6. January 2010 15:18

Recently I upgraded my development machine to Windows 7 and moved all daatabase files to it as well. When I tried to attach one of the database to SQL Server 2008, i got the following error.

Unable to open the physical file. 
Operating system error 5: "5(Access is denied.)". 
(Microsoft SQL Server, Error: 5120)

The error is very clear that it has everything to do with file system permissions on the database file. I searched around for answers to why SQL Management Studio is having issue although I am logged in as administrator on my machine. All the search results hinted that account under which SQL server is running does not have enough previlleges. So I was like so I just need to set appropriate permissions on MDF and LDF or any other database related files. The most dreaded suggestions that came across were people suggesting to give Full Control to the user account on the database folder(s). I am not going to go into discussion about this here why this is just bad. Lets just say that I am not a big fan of giving blanket full control permissions to user accounts to sensitive files without understanding what it means.

My SQL server instances were running under Network Service account. So I looked at the properties of the database folder and database files. And changed the permissions. Well that did not work. Since the error is very clear about the problem, it was time to do some old school debugging of problem. Since the error is related to file system, so it was time to fire up my good old Process Monitor tool. Now I was going to watch for Access Denied error when my database file was going to be accessed.

process monitor

What user account is used to access the database file?

If you can find the answer to this question, then all your problems are solved. So this is where Process Monitor is going to help. Start Process Monitor and try to attach the database file. Now capture the results from Process Monitor. You definitely will want to filter the results to include the entry related to your database file only. See the following image where the last entry for my database file has STATUS code of Access Denied. This is what I was looking for. Now double click on this entry and it will bring up details about that I/O operation. The following image shows the account that is being Impersonated to access this file. Yes, impersonation. When you start SQL Management Studio, it asks what kind of authentication you want to use. If you select currently logged in user or Windows Authentication that means SQL Management Studio is going to take all action on your behalf when accessing operating system resources.

sql server manager impersonation account

Fix It

Now you have two options to fix your problem.

  • If you are going to use Windows Authentication for SQL Management Studio, then you need to fix permissions on the database files to include that user with appropriate rights.
  • If you are going to use SQL Authentication, then make sure that account under which your SQL Server (and not SQL Management Studio) runs has correct set of permissions to access the physical files.

Making the above change should fix your problem and you will be able to attach the database without any errors.

Views: 1135

Tags:

SQL Server

How to use Bing Map Silverlight Control and add push pins for location markers

by Naveen 6. January 2010 07:35
Bing map silverlight control sdk

In one of my earlier posts Convert IP Addresss To Geo Location, I discussed how you can query a web service or database to get geo-location of that internet service provider. Now what do you do with that geo-location or spatial information. For one of the current Data Visualization projects I am working on, I had to show these locations on the map as well. The application is a Silverlight application so obvious choice was to find a control or component that I could drop in silverlight. And you pretty much have the answer, Use Bing Map Silverlight Control.

In this post I am going to discuss some of the following topics.

  • How to use Bing Silverlight Map Control?
  • How to add push pins to bing map?
  • How to add legends or some text to Silverlight Bing Map?
  • How to add regular silverlight controls on Bing Map control?

The documentation for Bing Map Silverlight control is still maturing and lacks lot of details. So most of the discussion in this post is based on personal experience and conversations I had through news groups and forums.

Set up development enviroment

Before you can start developing your silverlight application using Bing Map Silverlight control, you will need to do following things.

  • Create a developer account at Bing portal
  • As part of registration process, you will also be required to a credential key that is used with each request that you send to Bing web service to access data.
  • Download Bing Map Control SDK and install on your development machine.

Create Project and lets roll

Microsoft has provided a good walk through on Creating a Basic Application Using the Silverlight Map Control. I will strongly recomment going through it if its first time for you in Bing Map development.

Adding PushPin to Bing Map

Now that you have a vanilla implementation of map showing in your application. Next I want to add indicztors on the map to show location of internet service providers for which I have geo corodinates. There are few ways you can do. The most basic thing that you need to keep in mind is that Bing Map control is like any other silverlight control and can act as a container for other silverlight control. That means that I can just draw any shapes or objects at given corodinates. Well, you got it. Bing Map SDK provides some of these indicator controls out of the box. And one of them is PushPin. So what you need to do is crate instances of PushPin objects, set their longitude and latitude and add them as children of map control. Following code snippet shows how I added a collection of PushPin objects to my map control.

foreach(var loc in locations)
{
	var pp = new Pushpin() 
	  {Location = new Location(loc.Latitude, loc.Longitude)};
	UserLocationsMap.Children.Add(pp);
}

Adding DataGrid to Bing Map

Next task I had to do was to provide some summary of the data on the map itself. More precisely, I wanted to show how many service provides from each country I have in my database. For demo purposes I just needed to show name and count. I decided to add a DataGrid to map to show this data. Later on I am going to handle click events in this grid to have some interaction with the map as well. Since I already knew where I wanted to place the grid and what columns needed to be shown, I could just add this through XAML file itself. Following XAML snippet from the application shows how I have added a text block and data grid to Bing Map control as children.


<m:Map CredentialsProvider="xxxxxxxxxx" Name="UserLocationsMap">
 <m:Map.Children>
  <o:ShadowText x:Name="MapTitleText" ForegroundTop="Black" ForegroundBottom="Orange"
      Text="ISP Locations" FontFamily="Verdana" FontSize="24"
      HorizontalAlignment="Left" Margin="20,75,50,10"/>
	<StackPanel x:Name="CountryListPanel" Margin="20,250,50,10" Orientation="Vertical">
	 <data:DataGrid x:Name="CountryCountGrid" Width="150" Height="250"
	   AutoGenerateColumns="False" HorizontalAlignment="Left">
	  <data:DataGrid.Columns>
	   <data:DataGridTextColumn Header="Country" Width="SizeToHeader" Binding="{Binding Name}" />
	   <data:DataGridTextColumn Header="Count" Width="SizeToHeader" Binding="{Binding Count}" />
	  </data:DataGrid.Columns>
	 </data:DataGrid>
	</StackPanel>
	</m:Map.Children>
</m:Map>

Postioning on Map control

This is something you will have to play very close attention to. There is a difference between how controls or objects placed on map control. You must have noticed that when I added PushPin to map, I used longitude and latitude to position them on the map. But when I added DataGrid and ShadowText controls, I used Margin to control the placement. Most of the indiccator or layer objects that are provided in Bing Map SDK use gro-location values (longitude and latitude) to place object. But when you add regular silverlight controls on map, then you will control the position using Margin relative to origin of map control.

Views: 1439

Tags: ,

Bing Map | Silverlight

How to set silverlight column chart style programatically

by Naveen 4. January 2010 14:31

Let me wish a happy new year to all our blog readers.

This is first post of year 2010 and I decided to write my favorite topic of all times, Data Analysis and Visualization. These days I am working on a Silverlight application that involves very extensive use of charts for data visualization. And I use charting controls provided by Microsoft in Silverlight tool kit.

There are lot of examples available out there that shows you how to use these controls and how to style them. When it comes to styling and things like that, majority of the examples are focused around modifying control template or modifying styles in XAML file itself. Lot of time you make decisions about the type of chart and style of chart at run time based on data that needs to be visualized.

In this post I am going to focus on following tasks:

  • How to add a chart series programatically
  • How to set style of chart series programtically
  • How to set colors of columns in silveright charts programtically

Following image shows you a multi-series column chart. It shows three types of values at different intervals. One of the driving factor behind adding the column series was that I did not know how many different types of values are going to be returned in the data. So I could not simply add X number of ColumnSeries on XAML to say that I need to draw multi-series column chart with 3 points or things like that.

silverlight multiseries column chart

Following code snippet shows how I added column series in the main chart controls and how I specified different colors of the bars that are going to represent each type of data point.


foreach(LatencyColumnPlotData plotData in _latencyDataValues.ColumnPlotValues)
{
var series = new ColumnSeries();
var style = new Style(typeof (ColumnDataPoint));
SolidColorBrush bgBrush = (idx==1) ? 
    new SolidColorBrush(Colors.Blue) : 
    new SolidColorBrush(Colors.Orange);
var setterBg = new Setter(ColumnDataPoint.BackgroundProperty, bgBrush);
style.Setters.Add(setterBg);
series.DataPointStyle = style;
series.ItemsSource = plotData.DependentValues;
series.IndependentValueBinding = null;
series.Title = (idx == 1) ? "Average" : "Current";
idx++;
latencyChart.Series.Add(series);
}

var thresholdSeries = new ColumnSeries();
thresholdSeries.IndependentValueBinding = null;
thresholdSeries.ItemsSource = _latencyDataValues.ThresholdLatencyValues;
thresholdSeries.Title = "Threshold";
var bg = 
   new Setter(ColumnDataPoint.BackgroundProperty, new SolidColorBrush(Colors.Green));
var bgStyle = new Style(typeof(ColumnDataPoint));
bgStyle.Setters.Add(bg);
thresholdSeries.DataPointStyle = bgStyle;
latencyChart.Series.Add(thresholdSeries);

Views: 1229

Tags: , ,

Silverlight

Online DNN Dotnetnuke API Help

by Naveen 28. December 2009 07:41

Every time I am doing custom DNN module development, one thing will bug me all the time is having access to DNN Core API documentation. A lot of time I do not have access to local CHM file for help. That's when I used to wish if I had some place where online help is available for core api. So this x-mas i decided to be my own Santa Clause and give myself gift of online DNN core api help site. So here it is, You can click on the following link to visit my site where I have hosted DNN 5.2 Core API Help Documentation


Views: 768

Tags: ,

DotNetNuke

How to find current logged in user in DotNetNuke

by Naveen 18. December 2009 05:33

While developing DotNetNuke modules a lot of time you need to add features that have role based access control. To authorize the access, you will need the following set of information about the current user.

  • Is it authenticated session or anonymous user?
  • If its authenticated, who is the user?
  • What role(s) this user belongs to?
  • And other permissions related about information about the user

If you are not very familiar with DNN core API, then getting this information is not very obvious. And lack on online documentation of DNN API kind of makes it hard to search API as well. The API is very well done and has appropriate method names. But if there was an index, then it will be just quickly searching and getting the information.

Anyways, in DNN core, look in DotNetNuke.Entities.Users namespace. You will find two very useful classes UserController and UserInfo classes. As you may have guessed, these are two objects that you need to get user information. UserController has a static/friend method GetCurrentUserInfo that returns a UserInfo object. You can inspect this returned object to get more details about the user. For example, following code snippet shows how to find current logged in user in DNN and if this user is in particular role or not.


Dim userInfo = UserController.GetCurrentUserInfo()
if (userInfo.IsInRole("Manager")) Then
' Do some manager related work here
End If

You can explore UserInfo object to see what all you can do with it. Here is another example code that shows how to find all the roles of a user in DNN.

Dim userInfo = UserController.GetCurrentUserInfo()
Dim userRoles = userInfo.Roles

As you can see, the method names are very intutive and implemented at right place. Its just matter of knowing where to look for. If you have any questions about any DNN API, please feel free to drop me a line.

Views: 864

Tags: ,

DotNetNuke

How to insert emoticons into google wave

by Naveen 8. December 2009 06:14
emoticon in google wave

This is .Net implementation of recently published python Google Wave robot supasmiley. This is a very simple robot that parses the text in a blip. If there is some text that matches standard character combination for emoticon display, it replaces that text with a google wave gadget to display graphical display. In this example, the robot is only looking for character combination <3. If it is found, the range of characters are removed and gadget is inserted. The gadget is a simple flash movie that display beating heart.


 void ProcessEmotions(IEvent e)
 {
  var txtView = e.Blip.Document;
  var txt = txtView.Text;
  var idx = txt.IndexOf("<3");
  if (idx == -1)
  {
    return;
  }
  txtView.Delete(new Range(idx, idx+2));
  txtView.InsertElement(idx, new Gadget("http://wave.byteblocks.com/emotions-gadget.xml"));
}

Try It

  • Add byteblocks-emotions@appspot.com into your contact list.
  • Start a new wave or you can choose an existing wave
  • Add byteblocks-emotions@appspot.com as participant in the wave.
  • Enter text and where you want to show beating heart, type <3
  • ... like the heart now....

Download Sample Project

Views: 847

Tags:

Google Wave

How to set axis properties programatically for Silverlight charts

by Naveen 7. December 2009 06:23

In my previous post How to hide gridlines in charts, I showed how you can accomplish the task from XAML. This is all good when you know that rendering behavior of you chart is not going to change or you do not have to modify the display at run time based on some computed values curing run time. And works great for design time as well. But a lot of time you want to change the behavior at run time. In that case you need to know how you can change properties of axis programatically.

Each chart has a collection of Axis. By default this collection is empty. Charting controll fills this collection if you do not provide any. And it makes it decision based on the type of values you render on these axis. For example tf you are displaying DateTime type values on an axis, control will add DateTimeAxis to its collection. I have two liner axis in my chart that display simple numeric values. Following code shows how I added two linear axis, X and Y, to my chart. Most important property to set is Orientation. Without it, rendering engine does not know what axis you intend to change.


private void SetYAxis()
{
  var lax = new LinearAxis();
  lax.ShowGridLines = false;
  lax.Orientation = AxisOrientation.Y;
  lax.Title = "Response Time";
  myChart.Axes.Add(lax);
}

private void SetXAxis()
{
   var lax = new LinearAxis()
              {
                ShowGridLines = false,
                Title = "Interval",
                FontWeight = FontWeights.Bold,
                MaxHeight = 1,
                Opacity = 0,
                Orientation = AxisOrientation.X
               };
   myChart.Axes.Add(lax);
}

Views: 833

Tags: , ,

Silverlight | Charting

How to hide grid lines in Silverlight chart?

by Naveen 7. December 2009 05:53

This is one of the thing that is easy to do but no so obvious. I think mostly its lack of complete description of how charting controls provided in Silverlight toolkit work and how to manipulate them. When you draw charts like Line, Column, Bar etc., the grid line on DependentValue are rendered by default. There is a property ShowGridLines available on DisplayAxis class that is base class for axis. You just need to set its value to False. For example in my line chart I did not want to show grid lines on grid lines on Y axis. Following XAML snippets shows how I turned off rendering of grid lines on Y-axis.


<chartingToolkit:Chart Title="Latency" x:Name="latencyChart" BorderThickness="1">
 <chartingToolkit:Chart.Series>
  <chartingToolkit:LineSeries Title="Val 1" 
     DependentValueBinding="{Binding Threshold}"
     IndependentValueBinding="{Binding IndependentValue}" 
     AnimationSequence="Simultaneous" />
  <chartingToolkit:LineSeries Title="Val 2Latency" 
   DependentValueBinding="{Binding Current}" 
   IndependentValueBinding="{Binding IndependentValue}" 
   AnimationSequence="Simultaneous" />
  <chartingToolkit:LineSeries Title="Val 3" 
   DependentValueBinding="{Binding Average}" 
   IndependentValueBinding="{Binding IndependentValue}" 
   AnimationSequence="Simultaneous" />
  </chartingToolkit:Chart.Series>
   <chartingToolkit:Chart.Axes>
    <chartingToolkit:LinearAxis Orientation="Y" ShowGridLines="False"/>
  </chartingToolkit:Chart.Axes>
</chartingToolkit:Chart

Views: 841

Tags: , ,

Charting | Silverlight

Creating Email Rules Made Easy In Outlook 2010

by Naveen 4. December 2009 05:56

Yesterday I reconfigured my laptop and got myself fresh install of Windows 7. First thing I want to do on my machine is to get set up with my email client which happens to be Microsoft Outlook. I have been using Outlook 2007 for quite some time. I realized that I have a beta testing invite for Office 2010 sitting in my inbox from Microsoft. So I decided to give it a spin.

Download and install of Office 2010 went smooth. That was a good start. Now came time to configure my gazillion email accounts in email client. Having subscribed lot of development and technology news groups I get few thousand emails and it is always a challenge to organize them appropriately. So I rely very heavily on rules in Outlook. I always disliked Rules wizard in Outlook. I have to go through so many steps to create a simple rule. Only thing I want is simple one click operation that will set up rule like "move email from X to folder Z all the time". So I was looking around for my tool bar to see where rules wizard is. So there was a change for me. Now this Rules button is available in Move group of tool bar buttons. But I saw a small arrow below the button. I clicked on it and I was just thrilled. There is what I have been looking for all the time... One click option to set simple rule. By click of one button I was able to set up a simple email move rule. You can see the simple steps as shown below.

  • Find Move group of buttons in Outlook tool bar.

  • Click on the arrow below Rule button and it will bring up a simple menu below it. And select you rule condition.

  • Now select the folder where emails are to be moved. And you are done.

I could not ask for any thing more simple than this.

Views: 771

Tags:

Microsoft Outlook

Powered by BlogEngine.NET 1.4.6.1
Theme by Naveen Kohli

Recent

By Categories