ASP.NET MVC 4 RC on Windows Azure throws error “HTTP Error 403.14 – Forbidden ”

I’ve been playing with asp.net mvc 4RC and Windows Azure. I stumbled upon an issue when I deployed and tried to access the app in the cloud via browser. The following error was popping up “HTTP Error 403.14 – Forbidden”, it’s annoying, so everything was working on my laptop, though .  I’ve researched the problem and I figured it out, thanks to StackOverflow :),  that setting

<modules runAllManagedModulesForAllRequests="true">

could make the things work but this approach wasn’t the best one due to reasons explained by Colin in this blog : http://www.britishdeveloper.co.uk/2010/06/dont-use-modules-runallmanagedmodulesfo.html . So, having this configuration helped me to solve this problem:


<modules>
 <remove name="UrlRoutingModule-4.0" />
 <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
 </modules>

Best,

Rado

Advertisements

igGrid, merge json objects

I colleague of mine came to me and and showed me a screenshot of excel layout representing some data and asked me: “Is it possible to achieve this with igGrid?” He had some predefined data structure in form of json and he wanted to merge two columns in one.  Here is what the initial json structure was:


     {
		"Control":"xamDataChart",
		"Product_Impact":"Improvement",
		"Description":"Indexes of CategoryDateTimeXAxis should not resorted on every zoom level change of the chart.",
		"Notes":"Performance when zooming and panning with the CategoryDateTimeXAxis has been improved."
	},
	{
		"Control":"xamMap",
		"Product_Impact":"Fix",
		"Description":"When maximazing browser or WPF window, xamMap does not resize to fill up the whole area",
		"Notes":""
	}

He wanted to achieve the following layout:

“Notes” column should be merged to “Description”, Here is a function that I’ve came up with approaching this requirement.

   function merge(data) {
        //keep  the merged objects
        var mergedData = [];

        for (i = 0; i < data.length; i++) {

            /*Iterate through the arry elements*/
            //console.log(i);

            var mergedObject = {};
            var arrayElement = data[i];

            /*Iterate through the object properties */
            for (obj in arrayElement) {
                /*Merge Notes property to Description one*/
                if (obj == 'Notes' && '' != arrayElement[obj]) {
                    mergedObject['Description'] +=
						' </br> <span class="notesClass">Notes</span> '
                            + arrayElement[obj];
                } else {
                    mergedObject[obj] = arrayElement[obj]
                    //console.log(mergedObject);
                }
            }
            /* Add the newly created object to merged array*/
            console.log(i);
            mergedData.push(mergedObject);
        }
        return mergedData;
    }

If you are wondering how the igGrid looks in this scenario, here is  its definition:

    var template = "<tr><td><span class='row_template'>Control:</span> ${Control} </td>" +
	"<td><span class='row_template'>Product Impact: </span> ${Product_Impact} </td>" +
	"<td><span class='row_template'>Description: </span> ${{Description}} <span>  ${{Notes}} </span></td></tr>";

	$("#grid1").igGrid({

		autoGenerateColumns: false,
		rowTemplate: template,

		columns: [
					{ headerText: "Control", key: "Control" , width: '150px' },
					{ headerText: "Product Impact", key: "Product_Impact" , width: '110px' },
					{ headerText: "Description", key: "Description" , width: '900px' },
				    ],
        dataSource: merge(data),
        features: [
				        {
				            name: 'Sorting',
				            type: "local"
				        },
                        {
                        name: 'Filtering',
                        type: "local"
                        },
                        {
					            name: 'GroupBy'
				        }
			        ]
            });

I’ve used rowtemplate feature in order to achieve this layout.
More information about igGrid can be found here : http://samples.infragistics.com/jquery/grid
Best,
Rado

ASP.NET Web API

I’ve been looking at one of  the new  features of ASP.NET Web API and I decided to blog about it. I’ve used a Visual Studio 2010 with MVC 4 Tempalte for the blog.  Here is my experience on the matter.

It’s been said that the Web API  allows you to create services that can be exposed over HTTP rather than through a formal service such as WCF or SOAP.  When request comes a controller is picked up based on HTTP verb specified rather than on url.  Having communication over HTTP avoids complications with Firewalls and security issues.

The ASP.NET Web API includes support for the following features:

  • Modern HTTP programming model: Directly access and manipulate HTTP requests and responses in your Web APIs using a new, strongly typed HTTP object model.
  • Full support for routes: Web APIs now support the full set of route capabilities that have always been a part of the Web stack, including route parameters and constraints.
  • Content negotiation: The client and server can work together to determine the right format for data being returned from an API. There is provided support for XML, JSON, and Form URL-encoded formats.
  • Model binding and validation: Model binders provide an easy way to extract data from various parts of an HTTP request and convert those message parts into .NET objects which can be used by the Web API actions.
  • Filters: Web API  supports filters, including well-known filters such as the [Authorize] attribute.
  • Query composition: By simply returning IQueryable<T>, the  Web API will support querying via the OData URL conventions.
  • Improved testability of HTTP details: Rather than setting HTTP details in static context objects, Web API actions can now work with instances of HttpRequestMessage and HttpResponseMessage. Generic versions of these objects also exist to let you work with your custom types in addition to the HTTP types.
  • Improved Inversion of Control (IoC) via DependencyResolver: Web API now uses the service locator pattern implemented by MVC’s dependency resolver to obtain instances for many different facilities.
  • Code-based configuration: Web API configuration is accomplished solely through code, leaving your config files clean.
  • Self-host: Web APIs can be hosted in your own process in addition to IIS while still using the full power of routes and other features of Web API.

At the very beginning of this journey I run Visual Studio(VS)  then  chose from the VS menu “Create a New project” => “ASP.NET MVC 4 Web Application” after that I ended up  with the following solution structure:

solution

As can be seen it’s a pretty familiar ASP.NET MVC  app. I will list the structure of both controllers created by default,   HomeController and ValueController

HomeControler:

public class HomeController : Controller
{
      public ActionResult Index()
      {
          return View();
      }
}

ValueControler

public class ValuesController : ApiController
{
   // GET /api/values
   public IEnumerable&lt;string&gt; Get()
   {
      return new string[] { &quot;value1&quot;, &quot;value2&quot; };
   }
   // GET /api/values/5
   public string Get(int id)
   {
      return &quot;value&quot;;
   }
   // POST /api/values
   public void Post(string value)
   {
   }
   // PUT /api/values/5
   public void Put(int id, string value)
   {
   }
   // DELETE /api/values/5
   public void Delete(int id)
   {
   }
   }

An important point to notice  here is how the routes are defined. A quick look at the Global.cs file gives us the answer:

public static void RegisterRoutes(RouteCollection routes)
{
     routes.IgnoreRoute(&quot;{resource}.axd/{*pathInfo}&quot;);

     routes.MapHttpRoute(
       name: &quot;DefaultApi&quot;,
       routeTemplate: &quot;api/{controller}/{id}&quot;,
       defaults: new { id = RouteParameter.Optional });

routes.MapRoute(
       name: &quot;Default&quot;,
       url: &quot;{controller}/{action}/{id}&quot;,
       defaults: new { controller = &quot;Home&quot;,
           action = &quot;Index&quot;, id = UrlParameter.Optional });
}

Going forward I’ve made a test with Fiddler tool as I called the Get() method from our ValueController:

Fiddler - initiate request

Here is the response :

HTTP Response details

In the “Http Response details” screenshot is seen that the returned result by the Get() method is in form of JSON.  You can try to call the other methods as well through the Fiddler tool.

For additional information on the matter you can check out the following  links:

  1. http://aspnetwebstack.codeplex.com/
  2. http://www.asp.net/web-api

Hope have fun!

Best,

Rado

How to host multiple website on IIS 7.5

I had a case in which I had to host multiple website on IIS on port 80.

I was able to get it working with the steps below:

1. Go to IIS manager and pick up your website:

2. Click on “Edit Bindings ” option on the targeted website :

3. Edit the HTTP Host Name as enter the real Domain name:   

In your last step you need to go to your DNS provider and set A DNS record to point to the ip of your web server.

It’s time to test it  😉

Best,

Rado

WebDataGrid Manual CRUD

Purpose

WebDataGrid (WDG) has the capability to update the DataSource automatically if AutoGRUD property of EditingCore is set to true. What is “Manual CRUD”? This is a technique used by developers to persist all changes made in the grid UI to the DataSource by their own custom code. In this article I will go through the steps required to get WDG involved in Manual Crud scenario. I will demonstrate the setup of each behavior needed in order to make this happen. I will show how to use Editor Providers with AddNew Row feature also.

Preview

Image1

Required background

The article assumes you are familiar with WebDataGrid component. If you are not, consider the starting point at this link.

Prerequisites

If you intend to work with the article you will need the following:

  • Visual Studio 2010/2008
  • NetAdvanage for ASP.NET 11.2

Steps Overview

  1. Create new empty website in Visual Studio
  2. Setup your DataSource( in this step you can download the sample from the end of the article and copy App_Folder from the sample into your project)
  3. Create an Entity “Employee” and add the XMLParser class
  4. Drag WebDataGrid component form the toolbox onto the page
  5. Setup grid’s columns
  6. Setup RowAdding Behavior
  7. Setup RowDeleting Behavior
  8. Setup RowEditTemplate
  9. Handle CRUD operations on the server

Steps

  1. Open Visual Studio and create empty ASP.NET WebSite.
  2. Setup your DataSource. In this step I’ve created two classes, the first one is called “Employee” and the second one is XMLParser static class. The second is used as a bridge between underling DataSource, which is simply xml file,  and WDG.

The employee class definition:

  1. public class Employee
  2.     {
  3.         public string Name { get; set; }
  4.         public string Email { get; set; }
  5.         public string Team { get; set; }
  6.         public string Level { get; set; }
  7.         public string Office { get; set; }
  8.     }

The XMLParser class definition:

  1. /// <summary>
  2. /// Summary description for XmlParser
  3. /// </summary>
  4. public static class XmlParser
  5. {
  6.  
  7.     public static List<Employee> GetAllEmployees(string xmlFilePath)
  8.     {
  9.         try
  10.         {
  11.             List<Employee> employees = new List<Employee>();
  12.  
  13.             Object obj = new object();
  14.             XDocument document = null;
  15.  
  16.             lock (obj)
  17.             {
  18.                 document = XDocument.Load(xmlFilePath);
  19.             }
  20.             foreach (var element in document.Elements().Elements(“employees”).Elements(“employee”))
  21.             {
  22.                 employees.Add(new Employee()
  23.                 {
  24.                     Name = element.Element(“name”).Value,
  25.                     Email = element.Element(“email”).Value,
  26.                     Level = element.Element(“level”).Value,
  27.                     Team = element.Element(“team”).Value,
  28.                     Office = element.Element(“office”).Value
  29.                 });
  30.  
  31.             }
  32.  
  33.             return employees;
  34.         }
  35.         catch (Exception)
  36.         {
  37.             throw;
  38.         }
  39.  
  40.     }
  41.  
  42.     public static string GetFileOfAllEmployees(string path)
  43.     {
  44.         try
  45.         {
  46.             Object obj = new object();
  47.  
  48.             lock (obj)
  49.             {
  50.                 return XDocument.Load(path).ToString();
  51.             }
  52.         }
  53.         catch (Exception ex)
  54.         {
  55.             throw ex;
  56.         }
  57.     }
  58.  
  59.     public static XElement LoadFile(string path)
  60.     {
  61.         try
  62.         {
  63.             Object obj = new object();
  64.  
  65.             lock (obj)
  66.             {
  67.                 return XElement.Load(path);
  68.             }
  69.         }
  70.         catch (Exception ex)
  71.         {
  72.             throw ex;
  73.         }
  74.     }
  75.  
  76.     public static void SaveFile(XElement file, string path)
  77.     {
  78.         try
  79.         {
  80.             Object obj = new object();
  81.  
  82.             lock (obj)
  83.             {
  84.                 file.Save(path);
  85.             }
  86.         }
  87.         catch (Exception ex)
  88.         {
  89.             throw ex;
  90.         }
  91.     }
  92. }

Here is the definition of the XML file used as a persistent store:

  1. <?xml version=1.0 encoding=utf-8?>
  2. <team>
  3.   <configuration></configuration>
  4.   <employees>
  5.     <employee>
  6.       <office>US</office>
  7.       <name>Aaron</name>
  8.       <email>Aaron@company.com</email>
  9.       <level>0</level>
  10.       <team>XAML</team>
  11.     </employee>
  12.   </employees>
  13. </team>

      

        3. In this step drag the WDG from the Visual Studio toolbox on the page. If the controls are not in your toolbox even after you have installed them, here is a link which explains how to add the controls to the toolbox.

Image2

          5. In this step we will setup the WDG’s columns. Note that we set AutoGenerateColumns property to false, which means that over the data binding stage the grid will try to match the properties of the Entity from the DataSource that it is bound to, in our case “Employee” class. The key for each BoundDataField must match the property from the Employee class.

  1. <ig:WebDataGrid ID=”WebDataGrid1″ runat=”server” Width=”100%” AutoGenerateColumns=”False”
  2.       Height=”450px” StyleSetName=”IG”>
  3.       <Columns>
  4.           <ig:BoundDataField Key=”Name”>
  5.               <Header Text=”Name” />
  6.           </ig:BoundDataField>
  7.           <ig:BoundDataField Key=”Email”>
  8.               <Header Text=”Email” />
  9.           </ig:BoundDataField>
  10.           <ig:BoundDataField Key=”Level” DataType=”System.String”>
  11.               <Header Text=”Level” />
  12.           </ig:BoundDataField>
  13.           <ig:BoundDataField Key=”Team”>
  14.               <Header Text=”Team” />
  15.           </ig:BoundDataField>
  16.           <ig:BoundDataField Key=”Office”>
  17.               <Header Text=”Office” />
  18.           </ig:BoundDataField>
  19.       </Columns>

              6. In this step we will setup RowAdding Behavior (Feature) of the grid. This behavior allows the developer to add new rows to the WDG and persist them later when they are posted to the server either via full or ajax (partial) postback. The setup looks like this:

  1. <ig:RowAdding Alignment=”Top” EditModeActions-EnableOnActive=”true”>
  2.             <EditModeActions EnableOnActive=”True”/>         
  3.             <ColumnSettings>
  4.                 <ig:RowAddingColumnSetting ColumnKey=”Level”
  5.                     EditorID=”WebDataGrid1_DropDownProviderLevel”
  6.                     DefaultValueAsString=”Level” />
  7.                 <ig:RowAddingColumnSetting ColumnKey=”Team”
  8.                     EditorID=”WebDataGrid1_DropDownProviderTeam”
  9.                     DefaultValueAsString=”Team” />
  10.                 <ig:RowAddingColumnSetting ColumnKey=”Office”
  11.                     EditorID=”WebDataGrid1_DropDownProviderOffice”
  12.                     DefaultValueAsString=”Office” />
  13.             </ColumnSettings>
  14.         </ig:RowAdding>

As you might have already noticed in ColumnSettings tag I’ve specified Editor providers for few of the columns. The editor providers allow developers to edit a particular column through a given control. In our case the “Level” column is edited by DropDownEditor Provider. You easily can spot how the association is done through ColumnKey and EditorID. If you are wondering how the setup of the DropDownProvider is implemented, here is the answer:

  1. <ig:DropDownProvider ID=”WebDataGrid1_DropDownProviderLevel”>
  2.     <EditorControl
  3.     DropDownContainerWidth=”170%” DropDownContainerHeight=”100px”
  4.     DropDownContainerMaxHeight=”200px” EnableAnimations=”False” EnableDropDownAsChild=”False”>
  5.         <Items>
  6.             <ig:DropDownItem Selected=”false” Value=”0″ Text=”0″>
  7.             </ig:DropDownItem>
  8.             <ig:DropDownItem Selected=”False” Value=”1″ Text=”1″>
  9.             </ig:DropDownItem>
  10.             <ig:DropDownItem Selected=”False” Value=”2″ Text=”2″>
  11.             </ig:DropDownItem>
  12.             <ig:DropDownItem Selected=”False” Value=”3″ Text=”3″>
  13.             </ig:DropDownItem>
  14.         </Items>  
  15.     </EditorControl>
  16. </ig:DropDownProvider>

As a result of the completed setup above, the grid will allow adding new employees to our DataSource using EditorProviders. Here is the result:

Image3

     7.  In this step we will setup RowDeleting Behavior. Similar to the RowAdding Behavior, it allows adding new rows to the WDG, the RowDeleting feature gives us the possibility to delete rows from the grid..

  1. <ig:RowDeleting />

Is it so simple? Yes it is, in order to enable this feature we need to add the above line of code to the Behaviors tag. To see this feature in action you may select grid row and press the Delete button from the keyboard. The row will be deleted from the UI and post will be issued to the server. Alex Kartavov blogged about “Confirm WebDataGrid Row Deletion with Message Box” while ago. It is considered to be a good practice prior to deletion of any rows from the grid to prompt the user to confirm the action.

         8. RowEditTemplate is a great feature of the grid that allows developers to edit the grid easily. All you need to get it working is to go to the smart tag of the control and select Behaviors, then enable the RowEditingTemplate and click apply.

RET

Once you’ve enabled RET(RowEditTemplate) you can double click on the row selector for a particular row and experience it.

RET1

            9. Here I will show you how the server operations are handled and data are saved into the data store which is XML file in our case. I will go in details only for RowAdding handler. The code looks like this:

  1. void EditingCore_RowAdding(object sender, RowAddingEventArgs e)
  2. {
  3.     XElement emp = new XElement(“employee”,
  4.                     new XElement(“office”, 1),
  5.                     new XElement(“name”, 2),
  6.                     new XElement(“email”, 3),
  7.                     new XElement(“level”, 4),
  8.                     new XElement(“team”, 5)
  9.     );
  10.  
  11.     emp.Element(“name”).Value = e.Values[“Name”].ToString();
  12.     emp.Element(“office”).Value = e.Values[“Office”].ToString();
  13.     emp.Element(“email”).Value = e.Values[“Email”].ToString();
  14.     emp.Element(“level”).Value = e.Values[“Level”].ToString();
  15.     emp.Element(“team”).Value = e.Values[“Team”].ToString();
  16.  
  17.     XElement file = XmlParser.LoadFile(Server.MapPath(@”App_data\Employees.xml”));
  18.  
  19.     XElement element = new XElement(“employee”);
  20.     //element.
  21.     file.Element(“employees”).Add(emp);
  22.  
  23.     //file.Elements().Elements(“employees”).First()
  24.     try
  25.     {
  26.         file.Save(Server.MapPath(@”App_data\Employees.xml”));
  27.     }
  28.     catch (Exception)
  29.     {
  30.         throw;
  31.     }
  32.     finally
  33.     {
  34.         string path = Server.MapPath(@”App_data\Employees.xml”);
  35.         this.WebDataGrid1.DataSource = GetAllEmployees(path);
  36.         this.WebDataGrid1.DataBind();
  37.     }
  38. }

In this handler I update the xml file with the newly added record.

Hope you enjoy it !

Related Topics

http://help.infragistics.com/NetAdvantage/ASPNET/2011.2/CLR4.0/?page=Web_WebDataGrid_WebDataGrid.html

http://samples.infragistics.com/aspnet/ComponentOverview.aspx?cn=data-grid

 

How to more effectively get answers to your questions by Infragistics Engineers and Community?

Introduction

This post will cover how to more effectively get answers to questions you have using Infragistics products. Note that if you have a license it is important for you to register your keys to ensure that you get the correct level of support when you post to our forums or submit support cases. If you need to register your key you can do so on this link.

For more details on how our support systems work, see this

When posting questions formatting the content properly will ensure efficiency.

Before You Ask

Before you ask your question, consider the possibility that your question has been asked before and an answer may already be posted. Searching for an existing answer may be quicker than posting a question and waiting for a reply:

1. Look for an answer by reviewing our product guidance materials on: http://www.infragistics.com/support/documentation.aspx#OnlineDocumentation .

2. Search using our get help page at : http://www.infragistics.com/support/get-help.aspx

3. If you do not find answers to your question on our website please post it to our community forums at : http://forums.infragistics.com/

4. If your questions are about related technologies to our product you may also consider searching the web.

When You Ask

First check out our latest Support Policy: http://www.infragistics.com/support/default.aspx#SupportPolicies

Note: Infragistics recommendation – for all existing customers there is no difference where they ask a question. In all cases they are going to receive a response in a timely manner and we recommend the forums, because:

· Our advanced support infrastructure which gathers and prioritizes all support requests depends on the user support level

· We have a large community (more than 500k active users) and skilled Developer Support Engineers

The title of your question

Selecting a good title for the question/thread will be the one of the main driving forces for the community to want to actually read and answer your forum post.

The question

Provide all the necessary information in your initial post.

If applicable include information from the following categories:

  • Describe the symptoms of your issue carefully and clearly.
  • Describe the environment in which it occurs (OS, browser, application, frameworks). Provide your Infragistics product version (e.g.: “Windows 7 Enterprise SP1 64bit”, “IE 8”, “Silverlight 4.0.60129.0”, “Infragistics Silverlight 10.3.20103.2117” and etc.).
  • Describe the research you have done.
  • When Exceptions occur, it’s often very helpful to post the Call Stack of the Exception
  • Describe the diagnostic steps you took to try and pin down the problem yourself before you asked the question
  • Describe the expected behavior.

Please don’t let us assume, tell us right at the beginning.

Isolating an issue in a sample project

There are cases in which we simply cannot move forward without a project that would allow us to reproduce a specific issue locally in a controlled environment.

We usually ask for a sample project only after:

  • we have tried and couldn’t reproduce the reported issue by following your instructions
  • we have tried and couldn’t reproduce the reported issue by running the provided code snippet
  • we have tried and couldn’t reproduce the reported issue by intelligently predicting/guessing where the issue might be

You may follow the steps below to create isolated sample.

1. Clone the existing project – just to ensure that you will NOT lose any valuable data

2. Determine which controls, frameworks, data and code do not participate in the reproducing steps and are not needed to reproduce the issue. Often there are only 2-3 items which are directly involved in the reproducing steps, remove all other.

3. Move to separate simple project which reproduce the issue, by this way we will have really simple project using which we could easily reproduce and isolate the issue. Zip the project and attached it to your forum post/support ticket/email.

Screenshots

Sometimes it helps to send some screenshots or a movie that show the issue on your side. Here you can learn more how to create a screenshot at different OS:

http://en.kioskea.net/faq/141-print-screen-screen-capture-windows-mac-os-x-and-unix-linux

Follow-up

Follow up with a brief note on the solution. If one of the answers helped you, we would all like to know which one it was, and what you did to finally solve your problem. This is what an online community is all about – sharing information. Sharing information is not just by taking information from us, but also by sharing your success stories, and by helping others who might read your post in the future understand what the outcome of the thread was. Consider how you might be able to prevent others from having the same problem in the future.

This article was originally posted at Infragistics blog here