ASP.NET vNext

A few resources about ASP.NET vNext

Intro by Scott Hanselman : http://www.hanselman.com/blog/IntroducingASPNETVNext.aspx

Intro by David Fowler : http://davidfowl.com/asp-net-vnext/

  • A better platform for building web applications with .NET
  • Things we wanted to fix
  • System.Web

Overview by David Fowler : http://davidfowl.com/asp-net-vnext-architecture/

Intro by Jeff Fritz: http://developer.telerik.com/featured/microsofts-special-k-an-introduction-to-asp-net-vnext/

  • Introducing OWIN
  • MVC – Meet WebAPI, WebAPI meet MVC
  • Bye Bye System.Web
  • Blistering Performance
  • Where is web.config?
  • Welcome Project.JSON!

Videos :

Scott Hanselman and Scott Hunter : INTRODUCING: The Future of .NET on the Server

David Fowler and Scott Hanselman : DEEP DIVE: The Future of .NET on the Server

 

Source code :

Asp.Net vNext is open source and can be found on github : https://github.com/aspnet

The current version of ASP.NET is still on codeplex : http://aspnetwebstack.codeplex.com/

Incoming search terms:

  • asp net vnext ahref
  • oct vnext mvc
  • asp net vnext
  • asp net vnext grid
  • kendo ui vnext
  • vnext kendo
  • aspvnext upload
  • asp net vnext web config
  • asp net vnext how to instantiate class
  • asp net vnext deepdive

Optgroup with the Kendo UI Combobox

Kendo UI is a great framework to use, sometimes what you are looking for is not out of the box, but it’s not really difficult to make it work as you want to.

Kendo provides a combobox and a dropdown control, the following article uses the combobox for the example but applies for both controls.

What I want to achieve is to build a combobox with an optgroup.

Here is the raw html sample

<select>
 <optgroup label="Group 1">
 <option value="Value0">Option N°0</option>
 <option value="Value1">Option N°1</option>
 <!-- ... -->
 </optgroup>
 <optgroup label="Group 2">
 <option value="Value0">Option N°0</option>
 <option value="Value1">Option N°1</option>
 <!-- ... -->
 </optgroup>
 <optgroup label="Group 3">
 <option value="Value0">Option N°0</option>
 <option value="Value1">Option N°1</option>
 <!-- ... -->
 </optgroup>
 </select>

Using kendo, you can define a combox using the MVC wrappers this way

@(Html.Kendo().ComboBox()
 .Name("democombo").HtmlAttributes(new { style = "width:300px;" })
 .Filter("contains")
 .Placeholder("Select an item ...")
 .Items(x =>
 {
 // add some values
 x.Add().Text("Group 1");
 for (int i = 0; i < 10; i++)
 {
 x.Add().Value("value" + i).Text("Option N°" + i);
 }
 x.Add().Text("Group 2");
 for (int i = 0; i < 10; i++)
 {
 x.Add().Value("value" + i).Text("Option N°" + i);
 }
 //....

}))

it will look like this :

kendo combobox

There is a nice style and a search functionality, but since there is no way to specify that we want an optgroup, you cannot spot the difference between a simple item and a “group” item

Fortunately, it’s not that hard to make it work like if this option was existing.

Kendo ships with a template engine that will help

if we change a bit our code to make a clever user of the template :


@(Html.Kendo().ComboBox()
 .Name("democombo").HtmlAttributes(new { style = "width:300px;" })
 .Filter("contains")
 .Placeholder("Select an item ...")
 .Items(x =>
 {
x.Add().Text("Group 1").Value("optgroup");// notice that we give a value
 // ...
}).TemplateId("scriptTemplate"))

the template

// we use the value
<script id="scriptTemplate" type="text/x-kendo-template">
 # if ( Value=="optgroup") { #
 <div class="optgroup">#=Text#</div>
 # } else { #
 <div class="option">#=Text#</div> # } #
</script>

and the css


.k-list .k-item .optgroup {
 background: #fff;
 color: #000;
 font-weight: bold;
 }
 .k-list .k-item .option {
 padding-left: 15px;
 }

we are getting this result

kendo ui template

It’s nice but there is still two problems: the style on hover change, and the item is clickable

we can make use of the kendo combobox events to resolve that :


@(Html.Kendo().ComboBox()
 .Name("democombo").HtmlAttributes(new { style = "width:300px;" })
 .Filter("contains")
 .Placeholder("Select an item ...")
 .Items(x =>
 {
x.Add().Text("Group 1").Value("optgroup");
// ...
}).TemplateId("scriptTemplate").Events(events =>
 {
 events.DataBound(@<text>function(e){
// disable the click, and add a special class on the parent (which is the real item)
       $(".optgroup").parent().click(false).addClass("optgrouplistitem");
 }</text>);>
 }))

Some CSS to override the normal kendo “hover” style


.k-popup .k-list .k-item.optgrouplistitem.k-state-hover{
 border: none;
 color: #000;
 border-radius: 0;
 background: none;
 padding: 1px 5px 1px 5px;
 box-shadow: none;
 }

and we end with this

kendo optgroup

Complete code

<style type="text/css">
 .k-list .k-item .optgroup {
 background: #fff;
 color: #000;
 font-weight: bold;
 }

 .k-popup .k-list .k-item.optgrouplistitem.k-state-hover {
 border: none;
 color: #000;
 border-radius: 0;
 background: none;
 padding: 1px 5px 1px 5px;
 box-shadow: none;
 }

.k-list .k-item .option {
 padding-left: 15px;
 }
</style>

 

<script id="scriptTemplate" type="text/x-kendo-template">
 # if ( Value=="optgroup") { #
 <div class="optgroup">#=Text#</div>
 # } else { #
 <div class="option">#=Text#</div> # } #
</script>

 

@(Html.Kendo().ComboBox()
 .Name("democombo").HtmlAttributes(new { style = "width:300px;" })
 .Filter("contains")
 .Placeholder("Select an item ...")
 .Items(x =>
 {
 x.Add().Text("Group 1").Value("optgroup");
 for (int i = 0; i < 10; i++)
 {
 x.Add().Value("value" + i).Text("Option N°" + i);
 }
 x.Add().Text("Group 2").Value("optgroup");
 for (int i = 0; i < 10; i++)
 {
 x.Add().Value("value" + i).Text("Option N°" + i);
 }
 x.Add().Text("Group 3").Value("optgroup");
 for (int i = 0; i < 10; i++)
 {
 x.Add().Value("value" + i).Text("Option N°" + i);
 }

}).TemplateId("scriptTemplate").Events(events =>
 {

events.DataBound(@<text>function(e){
 $(".optgroup").parent().click(false).addClass("optgrouplistitem");
 }</text>);
 }))

Incoming search terms:

  • kendo combobox
  • kendoComboBox template tree
  • kendoDropDownList and optgroup
  • kendo select group items
  • kendocombobox
  • optgroup filter
  • kendo ui model for combobox
  • Kendo() DropDownList TemplateId
  • kendo optgroup
  • filter the kendo drop down list with 2 or 3 drop donlist

Quick tip : avoid .Parent.Parent.Parent…..

A simple way to avoid things like this :

HiddenField ct = (HiddenField)((Button)sender).Parent.Parent.Parent.Parent.Parent.Parent.Parent.FindControl("thehiddenidentifier");

is a simple loop


Control parent = ((Button)sender);
 do
 {
   parent = parent.Parent;
   ct = (HiddenField)parent.FindControl("thehiddenidentifier");
 }
 while (ct == null && parent != null);

You can make it an extension :


public static class ControlsXT
 {
 public static Control FindInParents(this Control ctrl, string searchidentifier)
 {
 Control foundControl;
 do
 {
 ctrl = ctrl.Parent;
 foundControl = ctrl.FindControl(searchidentifier);
 }
 while (foundControl == null && ctrl != null);
 return foundControl;
 }
 }

and use it this way :


HiddenField ct = null;
Control searchedControl = ((GroupRadioButton)sender).FindInParents("thehiddenidentifier");
if (searchedControl != null && searchedControl is HiddenField)
{
ct = (HiddenField)searchedControl;
}

what do you think ? do you have any other solutions ?

Incoming search terms:

  • jquery how to avoid parent parent parent

Quick tip: list all poco’s properties and their values

Let’s say you have a poco and you want to list all its properties whith their values for debug purpose (or other purposes : logs, …)

You can write something like this :


string porperties = "property1 : " + this.property1;
porperties+="property : " + this.property2;
// ..
porperties+="propertyn : " + this.propertyn;

but it’s long and painful, plus you can forget some properties

The reflection can help us here :


string porperties = "";
 foreach (System.Reflection.PropertyInfo f in this.GetType().GetProperties())
 {
porperties += f.Name + " : " + f.GetValue(this, null) + Environment.NewLine;
 }

And if you want to be a bit clever, you create a base object and redefine the ‘ToString() method like this:


public class POCOBase
{
public override string ToString()
{
string ret = "";
foreach (System.Reflection.PropertyInfo f in this.GetType().GetProperties())
{
ret += f.Name + " : " + f.GetValue(this, null) + Environment.NewLine;
  }
  return ret;
 }
}

Then just inherit from POCOBase and call the ToString() method

The output should be something like this :

AccountID : 10
ExternalREF : 090xfe
FIRSTNAME : USER 1
LASTNAME : TEST
PHONE : 00044440000
RegisterDate : 30/09/2009 16:20:02
Remark :

I think it’s quick, easy and useful

Simple proxy to bypass cors

CORS is a pain in the ass, all works great with chrome and firefox,but, as often, internet explorer doesn’t (it should work with ie 10 but you know…)

So the proxy solution is simple and works, even if I would prefer a full html/jquery solution.

To create a proxy for the get requests it’s simple.

Create an asp.net webform, add this in the pageload.


protected void Page_Load(object sender, EventArgs e)
{
 string serviceUrl = HttpContext.Current.Request.Params["service"];
 if (string.IsNullOrEmpty(serviceUrl))
 {
  return;
 }

 string query = string.Empty;
 int firstParamIndex = HttpContext.Current.Request.Url.Query.IndexOf('&');

 if (firstParamIndex > -1)
 {
  query = HttpContext.Current.Request.Url.Query.Remove(0,firstParamIndex+1);
 }

 string service = serviceUrl + "?" + query;

 WebClient client = new WebClient();

 foreach (string headerKey in HttpContext.Current.Request.Headers.Keys)
 {
  try
  {
    client.Headers[headerKey] = HttpContext.Current.Request.Headers[headerKey];
  }
  catch (Exception ex)
  {
    System.Diagnostics.Debug.WriteLine(ex.Message);
  }
 }

 // specify encoding : avoid special characters to be unrecognized.
 client.Encoding = Encoding.UTF8;
 string resultString = client.DownloadString(service);

 // carriage returns.
 Response.Write(resultString.Replace(@"\u000d\u000d", "<br/>"));
}

you can restrict some headers this way


protected void Page_Load(object sender, EventArgs e)
{
 string[] allowedHeaders =
 {
  "x-headers1",
  "x-headers2",
  "x-headers3"
 };

 string serviceUrl = HttpContext.Current.Request.Params["service"];
 if (string.IsNullOrEmpty(serviceUrl))
 {
  return;
 }

 string query = string.Empty;
 int firstParamIndex = HttpContext.Current.Request.Url.Query.IndexOf('&');

 if (firstParamIndex > -1)
 {
 query = HttpContext.Current.Request.Url.Query.Remove(0,firstParamIndex+1);
 }

 string service = serviceUrl + "?" + query;

 WebClient client = new WebClient();

 foreach (string headerKey in HttpContext.Current.Request.Headers.Keys)
 {
  if (allowedHeaders.Contains(headerKey))
  {
   try
   {
     client.Headers[headerKey] = HttpContext.Current.Request.Headers[headerKey];
   }
   catch (Exception ex)
   {
     System.Diagnostics.Debug.WriteLine(ex.Message);
   }
  }
 }

 // specify encoding : avoid special characters to be unrecognized.
 client.Encoding = Encoding.UTF8;
 string resultString = client.DownloadString(service);

 // carriage returns.
 Response.Write(resultString.Replace(@"\u000d\u000d", "<br/>"));
}

In your web client :


if (jQuery.support.ajax)
{
 $.ajax({
 headers:
 {
  "x-headers1": "header value 1",
  "x-headers2": "header value 2",
  "x-headers3": "header value 3"
 },
 contentType: "application/json; charset=utf-8",
 dataType: "json",
 url: "youpage.aspx?service=yourservicecompleteurl",
 data:
 {
  param1: value1,
  param2: value2
 },
 success: function (msg)
 {
  callback(msg);
 },
 error: function (errormsg)
 {
  if (errorCallback != 'undefined')
  {
  errorCallback(errormsg);
  }
 }
 });
 }
 else
 {
  alert('You browser doesnt support ajax.');
 }

I could use a webservice, but it would force me to do POST requests and I doesn’t want to make changes in my jscripts.

[Update 20120405 ]

Here is the full proxy code, which handles both get and post requests :


using System;
using System.Linq;
using System.Web;
using System.Text;
using System.Net;
using System.IO;

namespace yournamespace
{
 public partial class Proxy : System.Web.UI.Page
{
/// <summary>
/// Definition of the headers to transfer.
/// </summary>
private static string[] requiredHeaders =
{
"x-your-required-header-1",
"x-your-required-header-2",
"x-your-required-header-3",
"Content-type"
};

/// <summary>
/// Overrides the onload event to handle get and post requests.
/// </summary>
/// <param name="e"></param>
protected override void OnLoad(EventArgs e)
{
bool isPost = string.Equals(HttpContext.Current.Request.HttpMethod, "POST", StringComparison.OrdinalIgnoreCase);
string serviceUrl = HttpContext.Current.Request.Params["service"];
if (string.IsNullOrEmpty(serviceUrl))
{
return;
}

string service = serviceUrl + (isPost ? "" : "?" + GetQuery());
WebClient client = new WebClient();

// copy required headers
foreach (string headerKey in HttpContext.Current.Request.Headers.Keys)
{
if (requiredHeaders.Contains(headerKey))
{
try
{
client.Headers[headerKey] = HttpContext.Current.Request.Headers[headerKey];
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}
}

// specify encoding : avoid special characters to be unrecognized.
client.Encoding = Encoding.UTF8;
string resultString = string.Empty;
try
{
if (isPost)
{
client.Headers.Add(HttpRequestHeader.ContentType, "application/json");

using (MemoryStream str = new MemoryStream())
{
HttpContext.Current.Request.InputStream.CopyTo(str);
byte[] result = client.UploadData(service, str.ToArray());
resultString += Encoding.UTF8.GetString(result);
}
}
else // GET
{
resultString = client.DownloadString(service);
}
}
catch (WebException wex)
{
System.Diagnostics.Debug.Write(wex);
resultString = "<h1>An error occured : " + wex.Message + "</h1>";
resultString += "<br/>Status : " + wex.Status;
if (wex.Status == WebExceptionStatus.ProtocolError)
{
HttpWebResponse httpResponse = wex.Response as HttpWebResponse;
if (httpResponse != null)
{
resultString += string.Format("<br/>Status Code : {0}", httpResponse.StatusCode);
resultString += string.Format("<br/>Status Description : {0}", httpResponse.StatusDescription);
}
}
resultString += "<br/><br/>Requested service : " + service;
}
catch (Exception ex)
{
System.Diagnostics.Debug.Write(ex);
resultString = "<h1>An error occured : " + ex.Message + "</h1>";
resultString = ex.GetFullMessage();
resultString += "<br/><br/>requested service : " + service;
}
finally
{
client.Dispose();
}
Response.Clear();
Response.Write(resultString);
}

/// <summary>
/// Gets the query part.
/// </summary>
/// <returns></returns>
private static string GetQuery()
{
string query = string.Empty;
int firstParamIndex = HttpContext.Current.Request.Url.Query.IndexOf('&');
if (firstParamIndex > -1)
{
query = HttpContext.Current.Request.Url.Query.Remove(0, firstParamIndex + 1);
}

return query;
}
}
}

Incoming search terms:

  • cors proxy
  • bypass cors jquery
  • corsproxy
  • bypass cors
  • CORS and proxy
  • how to bypass cors
  • catch (webexception wex) sharepoint
  • bypass chrome cors
  • use proxy to support browser that doesnt support cors
  • ajax cors request behind client proxy