Peter's Blog   

Tourism in Czech Republic and other



 

This is just a small example how to use WebRequest and how to respond to it from an aspx page. Of course you could send your request to any other page which accepts POST requests. I have created a web application to test this behaviour as I will need it later in my project. There are some things you will need to watch out for. I've spent some time searching for the answers so hopefully you won't have to.

Step 1: Create a new web application and in the project properties set it so it runs on specific port. In my case I set it to port 45000. It is important for testing as when you use WebRequest.Create method, you must specify the URI exactly.

Step 2: Now setup your default.aspx with two textboxes - this is for the parameters you will be passing and two labels which will display the result of the webrequest.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>

<!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></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        Text 1
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        &nbsp;&nbsp;Text 2
        <asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
        &nbsp;<asp:Button ID="Button1" runat="server" Text="Post" OnClick="Button1_Click" />
        <br />
        <br />
        <br />
        Received Status:
        <asp:Label ID="Label1" runat="server"></asp:Label>
        <br />
        Received Response:
        <asp:Label ID="Label2" runat="server"></asp:Label>
    </div>
    </form>
</body>
</html>


Step 3: Setup a page which we are going to target. Something like CreateResponse.aspx. This page will do absolutely nothing only respond to your request so remove all the code after %>

This is important if you want to create responses to your requests ("Response.Write") and don't want to worry about the entire html it will return.

If you leave the <form> tag inside this page you may come across the following error after calling this page more than once.

The state information is invalid for this page and might be corrupted.


<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="CreateResponse.aspx.cs" Inherits="WebApplication1.CreateResponse" %>

 

Step 4: Write code behind the response page to do something. Notice the StatusDescription property it will work correctly only if you run your web application on IIS server. If you run this on VS development server it will always return default StatusDescription - OK.

using System;
using System.Net;
using System.Web;

namespace WebApplication1
{
    public partial class CreateResponse : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string strText1 = "";
            string strText2 = "";

            try
            {
                if (!string.IsNullOrEmpty(this.Request.QueryString["text1"].ToString()))
                {
                    strText1 = this.Request.QueryString["text1"].ToString();
                }
            }
            catch { }

            try
            {
                if (!string.IsNullOrEmpty(this.Request.QueryString["text2"].ToString()))
                {
                    strText2 = this.Request.QueryString["text2"].ToString();
                }
            }
            catch { }

            if (strText1 != "" || strText2 != "")
            {
                Response.StatusDescription = "Ok - got vars";
                Response.Write("Got this: - " + strText1 + " - " + strText2);
            }
            else
            {
                Response.StatusDescription = "Error - no vars";
                Response.Write("Got nothing at all");
            }
        }
    }
}


 

Step 5: And finally here is the code for you default.aspx page to create webrequest call.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;
using System.Net;
using System.IO;


namespace WebApplication1
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            string strText1 = HttpUtility.UrlEncode(TextBox1.Text);
            string strText2 = HttpUtility.UrlEncode(TextBox2.Text);

            string strParams = "text1=" + strText1 + "&text2=" + strText2;

            // Create a request using a URL that can receive a post.
            WebRequest request = WebRequest.Create("http://localhost:45000/CreateResponse.aspx?" + strParams);
            request.Method = "POST";
            string postData = "";
            byte[] byteArray = Encoding.UTF8.GetBytes(postData);
            request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = byteArray.Length;
            Stream dataStream = request.GetRequestStream();
            dataStream.Write(byteArray, 0, byteArray.Length);
            dataStream.Close();


            // Get the response.
            WebResponse response = request.GetResponse();           
            // Display the status.
            Label1.Text = ((HttpWebResponse)response).StatusDescription;
            // Get the stream containing content returned by the server.
            dataStream = response.GetResponseStream();
            // Open the stream using a StreamReader for easy access.
            StreamReader reader = new StreamReader(dataStream,Encoding.ASCII);
            // Read the content.
            string responseFromServer = reader.ReadToEnd();
            // Display the content.
            Label2.Text = responseFromServer;
            // Clean up the streams.
            reader.Close();
            dataStream.Close();
            response.Close();
        }
    }
}

 

Here is the source code for the above example...

WebApplication1.zip (153.80 kb)






For last couple of weeks I've been developing a custom module for MojoPortal website.
If you’ve followed the tutorials from Joe, you would build two projects to interact with sql data – data access layer and business layer project to allow support multiple databases (MySQL, MS SQL etc.).

I only needed to support MS SQL and as a big fan of LINQ (also being lazy) I’ve decided to use it instead of building data access layer for my project. So I’ll show you how I did that.

To simplify it we are going to build only the UI project. Create a new web application project in your mojoPortal solution. You will need to add all the references and required files. Have a look at the mojoPortal website for more details.

Now add a new data context file “abcLinq.dbml”. Open the abcLinq.dbml file and add some tables from your server explorer and save the dbml file.

The problem is that our abcLinqDataContext connection is now setup in the web.config or if you set abcLinqDataContext property connection - application settings to False then the abcLinqDataContext connection is hardcoded in the constructor (have a look at abcLinqDataContext()).

 

However if we want to use the connection setup in our user.config file “MSSQLConnectionString” we need to create a new class which inherits from abcLinqDataContext class. Here is the code for this.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace abcLinqUI
{
public class abcLinq_Ext : abcLinqDataContext
{
public abcLinq_Ext() :
base(global::System.Configuration.ConfigurationManager.AppSettings["MSSQLConnectionString"])
{
}
}
}

Now we can easily use this in our code. Note that we are now using the abcLinq_Ext() constructor.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace abcLinqUI
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
abcLinq_Ext db = new abcLinq_Ext();
var users = from u in db.mp_Users
where u.Trusted == true
select u;

GridView1.DataSource = users;
GridView1.DataBind();
}
}
}

 






Recently I've been asked to create a mega menu on an ASP.NET website which was using a standard ASP.NET menu control. Luckily for me I came across an article how to create a jQuery Mega Menu.

What I wanted to do is to combine the jQuery Mega Menu with standard ASP.NET menu using sitemap datasource.

Let's build a new website project from scratch so you can see clearly what you need to do to get your mega menu working with asp.net menu.

I'm going to repeat here some steps which are in the jQuery Mega Menu article

You need to download the following files and place them inside your website project.

- jkmegamenu.css - place this file in yoursite\App_Themes\Theme1\jkmegamenu.css
- jkmegamenu.js - place this file in yoursite\jscript\jkmegamenu.js
- jquery-1.3.2.min.js - place this file in yoursite\jscript\jquery-1.3.2.min.js





Step 1: Create a new master page. In the head tag you need to enter the following

<head runat="server">
<title>My Site</title>
<script type="text/javascript" src="jscript/jquery-1.3.2.min.js"></script>

<script type="text/javascript" src="jscript/jkmegamenu.js">
/***********************************************
* jQuery Mega Menu- by JavaScript Kit (www.javascriptkit.com)
* This notice must stay intact for usage
* Visit JavaScript Kit at http://www.javascriptkit.com/ for full source code
***********************************************/
</script>
</head>



Step 2: Now create a web.sitemap which will be used as our datasource for the menu.

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >

<siteMapNode url="~" title="Root"  description="">
<siteMapNode url="~/Default.aspx" title="Page1"  />
<siteMapNode url="~/Default2.aspx" title="Page2" >
<siteMapNode url="~/Default2_1.aspx" title="Page2_1" >
<siteMapNode url="~/Default2_1_1.aspx" title="Page2_1_1" />
<siteMapNode url="~/Default2_1_2.aspx" title="Page2_1_2" />
<siteMapNode url="~/Default2_1_3.aspx" title="Page2_1_3" />
</siteMapNode>
<siteMapNode url="~/Default2_2.aspx" title="Page2_2" >

<siteMapNode url="~/Default2_2_1.aspx" title="Page2_2_1" />
<siteMapNode url="~/Default2_2_2.aspx" title="Page2_2_2" />
<siteMapNode url="~/Default2_2_3.aspx" title="Page2_2_3" />
<siteMapNode url="~/Default2_2_4.aspx" title="Page2_2_4" />
<siteMapNode url="~/Default2_2_5.aspx" title="Page2_2_5" />
</siteMapNode>
<siteMapNode url="~/Default2_3.aspx" title="Page2_3" >
</siteMapNode>
</siteMapNode>

<siteMapNode url="~/Default3.aspx" title="Page3" >
</siteMapNode>
<siteMapNode url="~/Default4.aspx" title="Page4" >
</siteMapNode>
</siteMapNode>
</siteMap>



Step 3: Enter the following code in the master page within the form tag. Here we have our menu bound to SiteMapDataSource. We need to generate anchors ("anchorLiteral") and also html code for our mega menus ("menuLiteral"). I set the menu to fire OnDataBound event. Inside this event we can generate all the required code.

<asp:Literal ID="anchorLiteral" runat="server"></asp:Literal>
<asp:Literal ID="menuLiteral" runat="server"></asp:Literal>
<asp:Menu ID="Menu1" runat="server" StaticDisplayLevels="1" 
MaximumDynamicDisplayLevels="2" DataSourceID="SiteMapDataSource1" 
Orientation="Horizontal" OnDataBound="Menu1_DataBound">
</asp:Menu>
<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" 
ShowStartingNode="False" />




Step 4: Now we need to write the code behind the master page. The code loops through the menu items and generates required html code and scripts to get basic menu with mega menu dropdown.

protected void Menu1_DataBound(object sender, EventArgs e)
    {
        //hide the asp menu
        Menu1.Visible = false;
        
        //holds html anchors
        anchorLiteral.Text = "";

        //holds html mega dropdown menu
        menuLiteral.Text = "";

        //register megamenu script and create anchor foreach top level

        StringBuilder mScript = new StringBuilder();
        StringBuilder anchorText = new StringBuilder();
        StringBuilder menuText = new StringBuilder();

        mScript.AppendLine(@"<script type='text/javascript'>");
        int cntLvl1 = 0;
        
        foreach (MenuItem lvl1 in Menu1.Items)
        {
            cntLvl1++;
            string anchorId = "megaanchor" + cntLvl1.ToString();
            string megamenuId = "megamenu" + cntLvl1.ToString();

            //anchor for each top level menu
            anchorText.AppendLine("<a href='" + lvl1.NavigateUrl + "' id='" +
                anchorId + "' class='topMenuCMSListMenuLinkHighlighted'>" +
                lvl1.Text + "</a>");

            //building mega menu div if menuitem has children
            if (lvl1.ChildItems.Count > 0)
            {
                int cntLvl2 = 0;
                //script for each top level menu
                mScript.Append(@"jkmegamenu.definemenu('" + anchorId + "', '" + 
                    megamenuId + "', 'mouseover');");

                menuText.AppendLine("<div id='" + megamenuId + "' class=megamenu>");
                
                //building columns within the mega menu
                foreach (MenuItem lvl2 in lvl1.ChildItems)
                {
                    cntLvl2++;
                    menuText.AppendLine("<div class='column'>");
                    menuText.AppendLine("<h3><a href='" + lvl2.NavigateUrl + "'>" + 
                        lvl2.Text + "</a></h3>");

                    //create ul list if any children
                    if (lvl2.ChildItems.Count > 0)
                    {
                        menuText.AppendLine("<ul>");
                        foreach (MenuItem lvl3 in lvl2.ChildItems)
                        {
                            menuText.AppendLine("<li><a href='" + lvl3.NavigateUrl + "'>" + 
                                lvl3.Text + "</a></li>");
                        }
                        menuText.AppendLine("</ul>");
                    }

                    menuText.AppendLine("</div>");

                    //break after 2 columns
                    if (cntLvl2 >= 2)
                    {
                        menuText.AppendLine("<br style='clear: left' />");
                        cntLvl2 = 0;
                    }
                }
                menuText.AppendLine("</div>");
            }
        }

        anchorText.AppendLine("</ul>");

        anchorLiteral.Text = anchorText.ToString();
        menuLiteral.Text = menuText.ToString();
        mScript.AppendLine(@"</script>");
        Guid gid = System.Guid.NewGuid();

        Page.ClientScript.RegisterStartupScript(this.GetType(), gid.ToString(), mScript.ToString());

    }





Now here is the result.....





A friend of mine asked me for a help with his new website. I agreed and told him that I look into it in my spare time. I’m a .Net developer so my choice would be an open source CMS which would run on .NET platform and I wouldn’t have to spend long time learning it.
My main criteria were that the CMS should be easy to install, fast and free. This website needed a forum, a blog and polls. Also I like to stress that this is not for a corporate website but a small hobby website.
After some search on the web I ended up trying Mojoportal, DotNetNuke (DNN) and Umbraco.
Each of these products has very respectful following and of and their users have plenty of good things to say about each. So I had to dive in and do my own research which CMS would suite most.

DotNetNuke
It has been around a very long time. It is developed in VB.Net which was a bit of a drawback since I use C# but luckily for me you can develop modules in C#.
Installation was very easy and creation of my first few pages too. It performed well on my test server. Then I started to play with it more and setup a few modules - forum and blogs. The performance dropped and became rather slow.
I was reading around and there could be many factors why DNN can be slow....too many or wrong modules etc. I actually couldn’t find the right answer.
However, what I really liked about DNN is the amount of modules and skins you can buy or get for free. I think DNN is very mature product and if you have the time to learn it, it certainly will pay off.

MojoPortal
Fairly new player in the CMS field, done in C#, already plus for me and has some moderate number of followers. There are not many modules as I can see which are developed outside the main development group. However, the modules it has suited me just fine. I think the main drawback for many people when looking at MojoPortal is the look and feel – skin. The best thing would be to choose from around 40 different skins which come with the installation and then modify them.
After installing MojoPortal I felt very comfortable with it. It is really straight forward no fuss CMS. Performance was really impressive with all the all the modules I needed for the website. I also created a new module just to test how hard it is….it wasn’t.
When it comes to updating MojoPortal, it is very easy. All you need to do is to remember to copy a config file over, your own modules and skins.

Umbraco
As I read some reviews of this product I was really impressed and had to try it. So I read some docs and realized that you cannot run it on virtual directory. So you cannot just simply open the solution in your visual studio and press F5. So I setup Cassini web server and ran it from there. This is a major drawback for me since I want to have the flexibility of running the CMS from virtual directory.
Once I got it running, I started to poke around. It has very impressive user interface. Creating standard pages was easy. Then I tried to add a forum to it and I hit a wall. Someone suggested that you can setup YetAnotherForum to run with Umbraco but I just think it’s too much work unless you are setting up some serious website.
I’m sure that if you have the time to do your research and lots of learning this could be the product for you but I certainly would not recommend if you want to get a website up and running in a few days.


Conclusion
In the end it was DotNetNuke versus MojoPortal.
I Like them both but for me MojoPortal was the winner since it was the easiest to work with and it is very fast (which was a bit of a concern with DNN).






Great way to display data is using Microsoft Report Viewer on ASP.NET pages. However you don't want to create a new page for each report you generate. I came across this problem recently and decided that the best way for me would be to create just one page with a report viewer where I could display all my reports.


Now I'm going to show you how i did it...


Step 1

Under root folder I've created "Reports" folder. This is were I'm going to store all my reports (rdlc files) and a default page to display them.


Step 2

Create default.aspx under ~\Reports and place a MicrosoftReportViewer on it.


Step 3

Create new dataset "ReportsDataSet.xsd" under ~\App_Code. Here we are going to define the dataset classes.

The first datatable we need is for some general report parameters we would like to display on the report. So create a new datatable and add some columns to it. I've created a datatable called "Reports" with 3 columns - ReportName, ReportDate and Parameter1. I also added some tables from Northwind database. Just drag and drop from server explorer.

Now it should look like this.



Step 4

Create a new report under ~\Reports lets call it "CustomersReport.rdlc"

Goto Report - Data Sources and add ReportDataSet_Reports and ReportDataSet_Customers to your report sow we can use them.



Step 5

Design your report using selected datasources.



Step 6

Open ~\Reports\default.aspx.cs and enter the following code.

This is a method which loads "CustomersReport" in here you can load all the reports you wish.

private void ShowReport(string Report_Name, string Parameter1)
    {
        //path for your reports
        string path = HttpContext.Current.Server.MapPath("~/Reports/");

        ReportViewer1.Reset(); //important
        ReportViewer1.ProcessingMode = Microsoft.Reporting.WebForms.ProcessingMode.Local;
        Microsoft.Reporting.WebForms.LocalReport r = ReportViewer1.LocalReport;
        r.ReportPath = path + Report_Name + ".rdlc";
        Microsoft.Reporting.WebForms.ReportDataSource rds;


        // fill data parameters table so we can use it on reports
        DataTable dtReports = new ReportsDataSet.ReportsDataTable();
        DataRow drReports = dtReports.NewRow();
        drReports["ReportName"] = Report_Name;
        drReports["ReportDate"] = DateTime.Now;
        drReports["Parameter1"] = Parameter1;
        dtReports.Rows.Add(drReports);

        // add parameters table to report data source
        rds = new Microsoft.Reporting.WebForms.ReportDataSource();
        rds.Name = "ReportsDataSet_Reports";
        rds.Value = dtReports;
        r.DataSources.Add(rds);


        if (Report_Name == "CustomersReport")
        {
            ReportsDataSet.CustomersDataTable dtCustomers = new ReportsDataSet.CustomersDataTable();
            ReportsDataSetTableAdapters.CustomersTableAdapter ad = new ReportsDataSetTableAdapters.CustomersTableAdapter();
            ad.Fill(dtCustomers);

            rds = new Microsoft.Reporting.WebForms.ReportDataSource();
            rds.Name = "ReportsDataSet_Customers";
            rds.Value = dtCustomers;
            r.DataSources.Add(rds);
        }
    }



Now you can call this method within the ~\Reports\default.aspx page or you can call from other pages passing parameters. For that you will need this extra code.

protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            string reportName = null;
            string parameter1 = null;

            if (this.Request.QueryString["ReportName"] != null)
                reportName = this.Request.QueryString["ReportName"];

            if (this.Request.QueryString["Parameter1"] != null)
                parameter1 = this.Request.QueryString["Parameter1"];

            if (reportName != null)
            {
                ShowReport(reportName, parameter1);
            }
        }
    }



I'm just going to put a link on the home page to test that all works fine.

<a href="Reports/Default.aspx?ReportName=CustomersReport">Customers Report</a>



Here is the result.



Sign in