Sunday, May 31, 2009

No web.config found inside the latest release of DotNetNuke

If you have downloaded the latest version of DotNetNuke to play with it,and you have done all setup things correct still if you run the website then an error is thrown which says

Could not find file "c:\inetpub\wwwroot\DotNetNuke\web.config".

Exception Details: System.IO.FileNotFoundException: Could not find file "c:\inetpub\wwwroot\DotNetNuke\web.config".

Source Error:

Line 44:             ' open the web.config file
Line 45:             Dim xmlDoc As New XmlDocument
Line 46:             xmlDoc.Load(Common.Globals.ApplicationMapPath & "\web.config")
Line 47:             Return xmlDoc
Line 48:         End Function

This error is simply thrown as there is no web.config file inside the download if you have done whole source download.

This is because there are two other files called development.config and release.config

So the solution is just rename any of these files to web.config and you are done and ready to run your DotNetNuke installation.

Happy Programming!!!!!!!!!!!!!!!!!!!

Programming Challenge 1

Problem:-

  • There are two text files question.txt and the other is answer.txt

  • Question.txt have question in the below format

  •  
  • Taking example of the first line this file says that for question no 28 the answer is 2,similarly for question no 89 the answer is 1
  • Now we also have an answers.txt file in the below given format.
  • Now the simple puzzle to solve is that in answers.txt file each question answers are given they have 4 options as a1,a2,a3,a4.For example if the answer to question no 28 in questions.txt was given as 2 then in answers.txt file for questions[q28] [a2] we have to check its boolean value.If its true then a2 or 2 is one of the probable answers but we have to check all other answers as well because if any other is false then that also belongs to the set of answers.
  • So if for q28 a2 is true then in the finalanswers.txt file the answer set should contain 2, and if other options in answers.txt ie 1,3,4 any of them was false then that also should be there as an answer.

Solution:-

Solution is very simple but playing with string inside the text files is little messy.Also there can be various other alternative implementations to this.

We created three classes QuestionText,AnswerText,FinalAnswerText

public class AnswerText
    {
        public string A1 { get; set; }
        public string A2 { get; set; }
        public string A3 { get; set; }
        public string A4 { get; set; }

        public string CorrectAnswers { get; set; }
        public int QuestionNo { get; set; }

    }
    public class QuestionText
    {
        public int QNo { get; set; }
        public int Ans { get; set; }
    }
    public class FinalAnswer
    {
        public string FinalAns { get; set; }
    }

AnswerText contains A1,A2,A3,A4 as properties to store the values as extracted from the text file

QuestionText contains to properties Qno and Ans to store the correct ans and the question no which we will match against the list of answertext object.

public static List<QuestionText> ReadQuestions()
       {
           TextReader textReaderQuestion = new StreamReader("D:/Current Projects/QA/q.txt");
           String line;
           var questionList = new List<int>();
           var answerList = new List<int>();
           while ((line = textReaderQuestion.ReadLine()) != null)
           {
               string[] tempLine = line.Split(new char[] { '-' });
               int q, a;
               if (int.TryParse(tempLine[1], out q))
                   questionList.Add(q);
               if (int.TryParse(tempLine[2], out a))
                   answerList.Add(a);
           }
           var correctAnswer = answerList.ToArray();
           textReaderQuestion.Close();
           var questionTextList = new List<QuestionText>();
           var j = 0;
           foreach (int q in questionList)
           {
               var question = new QuestionText { QNo = q, Ans = correctAnswer[j]};
               questionTextList.Add(question);
               j++;
           }
           return questionTextList;
       }
   }
ReadQustions Function returns a list of QuestionText object.

public static List<AnswerText> ReadAnswers()
       {
           TextReader textReaderAnswers = new StreamReader("D:/Current Projects/QA/a.txt");
           string line;
           int i = 1;

           List<AnswerText> answerTextList = new List<AnswerText>();
           while ((line = textReaderAnswers.ReadLine()) != null)
           {
               if (!string.IsNullOrEmpty(line))
               {
                   AnswerText answerText = new AnswerText();
                   switch (i)
                   {
                       case 1:
                           answerTextList.Add(answerText);
                           answerText = answerTextList[answerTextList.Count - 1];
                           answerText.QuestionNo = CalculateQuestionNo(line);
                           i++;
                           break;
                       case 2:
                           answerText = answerTextList[answerTextList.Count - 1];
                           answerText.A1 = line.Trim();
                           i++;
                           break;
                       case 3:
                           i++;
                           break;
                       case 4:
                           answerText = answerTextList[answerTextList.Count - 1];
                           answerText.A2 = line.Trim();
                           i++;
                           break;
                       case 5:
                           i++;
                           break;
                       case 6:
                           answerText = answerTextList[answerTextList.Count - 1];
                           answerText.A3 = line.Trim();
                           i++;
                           break;
                       case 7:
                           i++;
                           break;
                       case 8:
                           answerText = answerTextList[answerTextList.Count - 1];
                           answerText.A4 = line.Trim();
                           i = 1;
                           break;
                   }
               }

           }
           textReaderAnswers.Close();
           return answerTextList;
       }

ReadAnswers returns a list of AnswerText objects.Switch case statement contains 8 cases as the pattern of the text file is like this as in the text file each question has an option line and one answer line i.e for each option we have 2 lines and thus in total 8 lines thus total 8 case statements.

public static FinalAnswer CreateAns(int ans, AnswerText ansObj)
       {
           var finalans = new FinalAnswer();
           finalans.FinalAns = String.Format("QNo-{0}-ans-", ansObj.QuestionNo);
           switch (ans)
           {
               case 1:
                   if (ansObj.A1 == "true")
                       finalans.FinalAns += "1,";
                   if (ansObj.A2 == "false")
                       finalans.FinalAns += "2,";
                   if (ansObj.A3 == "false")
                       finalans.FinalAns += "3,";
                   if (ansObj.A4 == "false")
                       finalans.FinalAns += "4,";
                   break;
               case 2:
                   if (ansObj.A1 == "false")
                       finalans.FinalAns += "1,";
                   if (ansObj.A2 == "true")
                       finalans.FinalAns += "2,";
                   if (ansObj.A3 == "false")
                       finalans.FinalAns += "3,";
                   if (ansObj.A4 == "false")
                       finalans.FinalAns += "4,";
                   break;
               case 3:
                   if (ansObj.A1 == "false")
                       finalans.FinalAns += "1,";
                   if (ansObj.A2 == "false")
                       finalans.FinalAns += "2,";
                   if (ansObj.A3 == "true")
                       finalans.FinalAns += "3,";
                   if (ansObj.A4 == "false")
                       finalans.FinalAns += "4,";
                   break;
               case 4:
                   if (ansObj.A1 == "false")
                       finalans.FinalAns += "1,";
                   if (ansObj.A2 == "false")
                       finalans.FinalAns += "2,";
                   if (ansObj.A3 == "false")
                       finalans.FinalAns += "3,";
                   if (ansObj.A4 == "true")
                       finalans.FinalAns += "4,";
                   break;
           }
           return finalans;
       }

CreateAns takes two parameters one is the ans which is of type int , it is the answer given in the question.txt file and the other parameter is the AnswerText object from which we will get the question no and value of other options and here only we will match whether the given answer in the questions.txt file is valid or not and also in this we will check for other valid answers.And finally return a finalans string.

public static List<FinalAnswer> CalculateAnswers(List<QuestionText> qtl, List<AnswerText> atl, List<FinalAnswer> ftl)
       {
           foreach (QuestionText qObj in qtl)
           {
               var qno = qObj.QNo;
               var ansObj = atl.Find(ans => ans.QuestionNo == qno);
               if(ansObj != null)
               {
                   var finalAns = CreateAns(qObj.Ans, ansObj);
                   ftl.Add(finalAns);
               }
           }
           return ftl;
       }

CalculateAnswers return the list of FinalAnswer objects ready to be written in the finalanswer.txt file after implementing all the logic.

Download the source for this article from QuestionSolution

Instructions for using the code

Please change the directory path to read and write the text files according to your choice.

Happy Programming!!!!!!!!!!!!!!!!!!!!!

Thursday, May 28, 2009

301 Redirect using Asp.net and asp

Many times we move our webpages or our entire website from one domain to another or change the address of some of the pages inside the website.

All such moving of pages is painful for a user who simply deletes the pages from the old server and copies them to the new server or maps them to the new server or domain.

In such a scenario a user looses every SEO which was related to his links earlier.So for preventing such type of SEO loss we make use of 301 Redirects.

301 Redirects stand for moved permanently.This tells the browser that this page is moved permanently from the old location to the new location.The benefit of using 301 Redirects is that the search engine,crawlers and other bots respect 301 redirects and preserve and SEO information related to the old link, It simply tells the search engines that the page location has permanently moved and you need to index the page from the new location in future.

There is also another form of redirect known as 302 redirect but this redirect is the temporary redirect thus its also not beneficial from the SEO point of view.

301 redirects can be achieved in many ways and ways are different for different type of programming languages and operating systems of the server which you are using.

301 redirects can be very easily achieved by using .htaccess file if you are using linux servers.

But if you programmatically want to impose a 301 moved permanently redirect then you can easily do this by placing this piece of code on your aspx page if you are using asp.net

<script runat="server">
private void Page_Load(object sender, System.EventArgs e)
{
Response.Status = "301 Moved Permanently";
Response.AddHeader("Location","http://www.smallworkarounds.com/jqnetgrid/jqnetgridhome.aspx");
}
</script> 

Placing this code in your aspx page will redirect your page whenever it loads to a page specified in the Response.AddHeader parameter

Response.Status is used to make entry in the header which says that this page has been permanently moved to another location.

Also same 301 redirection can be achieved if we place the same piece of code inside the Page_Load method in the code behind file

protected void Page_Load(object sender, System.EventArgs e)
        {
		       string NewMedUrl = "http://www.smallworkarounds.com/jqnetgrid/jqnetgridhome.aspx";
                Response.Clear();
                Response.Status = "301 Moved Permanently";
                Response.AddHeader("Location", NewMedUrl);
                Response.End();
        }

In classic asp to achieve the same functionality we would do

<%@ Language=VBScript %>
<%
Response.Status="301 Moved Permanently"
Response.AddHeader "Location", "http://www.smallworkarounds.com/jqnetgrid/jqnetgridhome.asp"
%>

Also please make are sure recheck whether your pages are redirecting correctly or not after writing the redirect code.

There are few other ways to redirect your pages using 301 moved permanently redirect.But this is the most efficient way to redirect pages using the code.

At the IIS level you can also set the redirect to property of any file to make it redirected to the desired location.