Key practice of MVVM in XAMP apps

In XAML based apps i.e. Silverlight, WPF, Windows store and windows phone apps there are many ways to bind objects or collections with control properties.

In order to bind it with textbox (suppose), one way is to set the DataContext property of the container i.e. Grid, StackPanel etc. and bind it using {Binding Path=PropertyName} where property name could be any property of the object binded with the DataContext property of the container. There are many ways of binding shown in my other article https://ovaismehboob.wordpress.com/2011/06/20/wpf-data-binding-options/

Although there are many other ways of binding, but for example if you want to update the control property when the object value modifies real problem comes in. In order to achieve this we can implement MVVM pattern. MVVM works with Model, View and ViewModel. Where a Model represents a domain model, View contains controls whereas the ViewModel is the model of a view and contains the properties, events, etc. particularly to the View. In order to handle this scenario, we can create a ViewModel in this below example and then bind it to the view in the later stage. To notifying UI thread we have to implement INotifyPropertyChanged interface.

public
class
TestViewModel: INotifyPropertyChanged

 

{


public RegistrationViewModel()

{

attributes = new
ObservableCollection<String>();

}

 


public
event
PropertyChangedEventHandler PropertyChanged;

 


string _name;

 


public
string Name

{

 


set { this._name = value;

NotifyChangeEvent(“Name”);

}


get { return _name; }

}

 


ObservableCollection<String> _attributes;

 


public
ObservableCollection<String> Attributes

{


set

{


This._attributes = value;

NotifyChangeEvent(“Attributes”);

}


get { return _attributes; }

 

}

 

 

 


void NotifyChangeEvent(string propName)

{


if (PropertyChanged != null)

PropertyChanged(this, new
PropertyChangedEventArgs(propName));

}

}

 

 

In the above code you can see I have two properties Name and Attributes. While setting Name value I am calling NotifyChangeEvent that checks the event and call invoke if it’s not null.

You may notice that the Attributes collection is ObservableCollection and not List, etc. if we set it to List, etc. it does not notifies any modification happens to the collection. http://msdn.microsoft.com/en-us/library/ms668604(v=vs.110).aspx

 

Now let suppose you have a form containing two textboxes and a list.

XAML as follows


<Grid Name=”grdreg” Background=”{ThemeResource ApplicationPageBackgroundThemeBrush}”>


<TextBox
Name=”txtBox” HorizontalAlignment=”Left” Height=”124″ Margin=”161,128,0,0″ TextWrapping=”Wrap”
VerticalAlignment=”Top” Width=”297″/>


<TextBox Name=”txtBox2″ HorizontalAlignment=”Left” Height=”142″ Margin=”161,276,0,0″ TextWrapping=”Wrap” Text=”{Binding Path=Name}” VerticalAlignment=”Top” Width=”423″/>


<Button Content=”Update” HorizontalAlignment=”Left” Height=”130″ Margin=”475,125,0,0″ VerticalAlignment=”Top” Width=”112″ Click=”Button_Click”/>


<ListBox ItemsSource=”{Binding Path=Attributes}”
HorizontalAlignment=”Left” Height=”290″ Margin=”616,128,0,0″ VerticalAlignment=”Top” Width=”159″/>

 


</Grid>

The first textbox in white is a TextBox control (txtBox) and the second in gray is also a TextBox control (txtBox2), whereas the right one in vertical is ListBox. In the XAML, you can bind any object property like {Binding Path=PropertyName} and in this snippet the txtBox is binded with Name property like {Binding Path=Name}.

For list control you can set ItemsSource property and use the same {Binding Path=PropertyName} to bind with specific collection property. Now how does the runtime know which object property has to be mapped. This can be done by specifying the DataContext property of the container where all controls reside and this I have set it in the code-behind (You can also set in XAML)

Code behind

public
sealed
partial
class
BlankPage1 : Page

{

 


RegistrationViewModel viewModel;


public BlankPage1()

{


this.InitializeComponent();

 

viewModel= new
RegistrationViewModel();

grdreg.DataContext = viewModel;

}

 


private
void Button_Click(object sender, RoutedEventArgs e)

{

viewModel.Name = txtBox.Text;

viewModel.Attributes.Add(txtBox.Text);

}

}

}

On page constructor I am initializing the viewModel and setting it to the DataContext property of grid container “grdreg”.

That’s all…

you can start modifying values of the view model, UI will be updated accordingly.

Tip: In case you have apps for different platforms namely Silverlight, windows phone and windows store apps etc. you can use Portable Class Library and place all your view models there. http://msdn.microsoft.com/en-us/library/gg597391(v=vs.110).aspx

Sync Calendar Events using CALDAV in C#

In this post I will walk you through the steps of reading calendar events from CALDAV supported servers. Yahoo, Google, etc. supports CALDAV

What is CALDAV?

CALDAV is an internet standard allowing client to access scheduling information on remote server. It’s an extension of WebDAV which is a HTTP-based protocol for data manipulation. The protocol is defined by RFC 4791. As it’s an extension to WEBDAV protocol it uses HTTP verbs to manipulate calendar events some of them mostly used are PROPFIND, SEARCH, etc.

Background Information

  1. Every server has a separate URI to access calendar events.

Yahoo: https://caldav.calendar.yahoo.com/dav/user_name/Calendar/calendar_name/

Google: https://www.google.com/calendar/dav/user_name/events/

  1. Each Calendar folder is a collection and contains many calendar events. Each calendar event is a file and ended with .ics extension. .ics is well understood by many clients and you can easily export data from .ics to local client application.

How to Program

Now let’s see how to write a code to call Yahoo calendar events

  1. First of all create a new project in Microsoft Visual C# .NET
  2. Add reference to DDay.iCal library from Nuget Package manager console. This library will be used to read .ics files and read information about each event.
  3. Write below code to retrieve calendar event on any click event.

     


    In the above code snippet you have to configure your user name, password and modify the calendar URI depending on your calendarname and username.

If you see the code, I specified a content string which contains the request that I am sending it to the server. CALDAV have specific request formats which you can study here

ExecuteMethod is a helper method that sends request to the server and returns the response stream. Once I get the response stream I load the XML document and read the InnerXml of the file to get the complete XML. Then I parse the xml document and search for DAV:href element that contains the calendar event file (.ics) information. Once I get the list of .ics file paths, I call DownloadICS helper method to get the complete event information.

Helper Methods
Following are the helper method that performs specific operations. Please write these in your code to compile the project.

DownloadICS – Downloads .ics files


 

ExecuteMethod: Request calendar and returns response stream


Certificate error when deploying WCF Azure Service

Last night I was working on some Azure WCF Service and while deploying on the Windows Azure Platform, I continuously faced error that “The certificate with thumbprint was not found in windows azure”. It was a simple WCF service based on BasicHttpBinding and has few operation contracts.

After doing deep research I found that while packaging a service from Package Windows Azure Application window, if you select “Enable Remote Desktop for all roles” or “Enable Remote Debugger for all roles” it expect to have certificates uploaded on azure portal and you should have specified the exact thumbprint in the Certificates section from properties window. Otherwise your deployment does not succeed.

Therefore, I succeeded disabling these two checks while creating a package and also made sure that there were no <certificates></certificates> tags inside service definition (.csdef) file and service configuration (.cscfg) file.

Hope this helps!

Creating Custom Formatter in ASP.NET Web API for specific formatted response

In this article I will show you how to create a custom formatter in ASP.Net Web API to send formatted response.

Before diving into deep, let me give you a quick introduction to formatters

Formatters in ASP .NET Web API plays an important role, when the request comes to the server, depending on the media-type, determines which formatter has to be used to parse the request and assemble the data into appropriate format as response. In ASP.Net Web API when the request is made by the user, Web API framework checks if it is Simple Type or a Complex Type. All types like string, integers, etc. are simple types and by default ASP.Net Web API read those values from URI and uses Model binding. On the other hand for complex types, ASP.Net WEB API framework read it from request body by default (the behavior can be overridden) an depending on the content-type load specific formatter from the list of formatters available in HttpConfiguration list.

When you are creating a custom formatter in ASP.Net Web API, you have two options one is when the request is arrived on server and you want to return the data in specific format or when the request arrives and you want to read/parse the data in specific format.

In this example, we will see how you can return the response in PSV i.e. pipe separated value format.

Create a class that should be derived from BufferedMediaTypeFormatter or MediaTypeFormatter.

The difference is

  • MediaTypeFormatter – This class uses asynchronous read and write methods.
  • BufferedMediaTypeFormatter – This class derives from MediaTypeFormatter but wraps the asynchronous read/write methods inside synchronous methods. Deriving from BufferedMediaTypeFormatter is simpler, because there is no asynchronous code, but it also means the calling thread can block during I/O

In the example, we will use BufferedMediaTypeFormatter

Following are the methods available in BufferedMediaTypeFormatter class

// Summary:


// Represents a helper class to allow a synchronous formatter on top of the


// asynchronous formatter infrastructure.


public
abstract
class
BufferedMediaTypeFormatter : MediaTypeFormatter

{


// Summary:


// Initializes a new instance of the System.Net.Http.Formatting.BufferedMediaTypeFormatter


// class.


protected BufferedMediaTypeFormatter();

 


// Summary:


// Gets or sets the suggested size of buffer to use with streams in bytes.


//


// Returns:


// The suggested size of buffer to use with streams in bytes.


public
int BufferSize { get; set; }

 


// Summary:


// Reads synchronously from the buffered stream.


//


// Parameters:


// type:


// The type of the object to deserialize.


//


// readStream:


// The stream from which to read


//


// content:


// The System.Net.Http.HttpContent, if available. Can be null.


//


// formatterLogger:


// The System.Net.Http.Formatting.IFormatterLogger to log events to.


//


// Returns:


// An object of the given type.


public
virtual
object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger);


//


// Summary:


// Reads asynchronously from the buffered stream.


//


// Parameters:


// type:


// The type of the object to deserialize.


//


// readStream:


// The stream from which to read.


//


// content:


// The System.Net.Http.HttpContent, if available. Can be null.


//


// formatterLogger:


// The System.Net.Http.Formatting.IFormatterLogger to log events to.


//


// Returns:


// A task object representing the asynchronous operation.


public
override
sealed
Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger);


//


// Summary:


// Writes synchronously to the buffered stream.


//


// Parameters:


// type:


// The type of the object to serialize.


//


// value:


// The object value to write. Can be null.


//


// writeStream:


// The stream to which to write.


//


// content:


// The System.Net.Http.HttpContent, if available. Can be null.


public
virtual
void WriteToStream(Type type, object value, Stream writeStream, HttpContent content);


//


// Summary:


// Writes asynchronously to the buffered stream.


//


// Parameters:


// type:


// The type of the object to serialize.


//


// value:


// The object value to write. It may be null.


//


// writeStream:


// The stream to which to write.


//


// content:


// The System.Net.Http.HttpContent, if available. Can be null.


//


// transportContext:


// The transport context.


//


// Returns:


// A task object representing the asynchronous operation.


public
override
sealed
Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext);

}

 

When we derive our custom formatter class from BufferedMediaTypeFormatter class we have to override following methods.

 

public
override
bool CanWriteType(Type type)

 

public
override
void WriteToStream(Type type, object value, System.IO.Stream stream, System.Net.Http.HttpContent content)

 

We can put some logic inside CanWriteType method that checks the type and return true or false. If the resultant value is true the framework calls WriteToStream method otherwise the WriteToStream method won’t be called.

Here is the complete code of custom formatter.


public
class
PsvFormatter : BufferedMediaTypeFormatter

{


public PsvFormatter()

{

SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue(“text/pipe”));

 

}


public
override
bool CanWriteType(Type type)

{


if (type == typeof(Session))

{


return
true;

}


return
false;

}

 


public
override
void WriteToStream(Type type, object value, System.IO.Stream stream, System.Net.Http.HttpContent content)

{


using (var writer = new
StreamWriter(stream))

{

 


var singleSession = value as
Session;


if (singleSession == null)

{


throw
new
InvalidOperationException(“Cannot serialize type”);

}

WriteItem(singleSession, writer);

}

stream.Close();

 

}

 


private
void WriteItem(Session session, StreamWriter writer)

{

writer.WriteLine(“{0}|{1}|{2}|{3}”, session.Id,

session.SessionName, session.SessionDateTime, session.Place);

}

 

}

 

In the above code snippet, if you see the constructor I have added the Media type header value in the SupportedMediaTypes list which will be used to pass in the request header information. While invoking WEB API method you can pass text/pipe as ACCEPT header attribute.

In the CanWriteType method I am checking if the type of the object which I am returning is of type Session. In my code example I have a Session whose structure is as follows.

public
class
Session

{


public
int Id { set; get; }


public
string SessionName { set; get; }


public
DateTime SessionDateTime { set; get; }


public
string Place { set; get; }

}

 

In the WriteToStream method I am using the stream writer and writing the object as pipe separated string.

Now in the DataController which is the Web API controller, I have a Get method which fetches the session object from database. After fetching the session object from database, web API framework calls CanWriteType and WriteToStream method and parse the object into Pipe separted string and send that string as the response.

public
class
DataController : ApiController

{


public
Session Get()

{


return repository.All<Session>().Where(i => i.Id == 3).First();

}

}

Using fiddler, I made a request to my data controller and passed text/pipe as ACCEPT attribute this tells the framework that the return response should be text/pipe. Web API framework checks the formatter and uses my custom formatter to serialize the response in pipe separated string.


And the response is here


You can see how easy it is to implement custom formatter in ASP.Net WEB API and in the next series of article I will blog a post about handling custom content type requests in ASP.Net Web API

Hosted two Sessions on MS Dynamics CRM and ASP .NET Web API @ Microsoft

As a group leader of Microsoft Technology Practices User Group i.e. http://meetup.com/mstpug, organized two sessions this week at Microsoft Innovation Center, Karachi.

First Session: Customizing MS Dynamics CRM

Speaker: Asif Fattah

Linked In Profile: http://www.linkedin.com/pub/asif-fattah/20/69b/972

Session Duration : 1 hour

 

Second Session: Detailed Overview on ASP .NET Web API

Speaker: Me (Ovais Mehboob Ahmed Khan)

Linked In Profile: http://pk.linkedin.com/in/ovaismehboob/

Session Duration: 1 hour

 

It was both online and on-location event in which some of our group members have attended the event by visiting onsite and few joined online via Lync.

We are planning to organize more events in future and in order to get updates please join us and become a group member by following this link http://meetup.com/mstpug. Group members can get benefitted by monthly Plural Sight subscriptions depending on how active they participate. Also, the presentations and webcast of previous sessions are available on the user group website.

Few snaps:





At last, I would like to thank Microsoft for providing us space and services to organize our events.

Reducing XAP size of Silverlight Client apps

In this article I would like to share my experience related to the hosting of Silverlight Chat applications on real production servers and accessing it over internet.

I developed a Silverlight chat application based on Silverlight 5 and ASP.Net that’s works perfectly and runs smoothly but sometimes take some time to download and load a Chat Panel (that was based on Silverlight) which seems quite notorious. After doing some R&D I came to know that with simple configuration from Visual Studio on your project settings page you can compress the XAP file size and make your life easier.

As in the project I used Telerik and AJAX toolkit controls and some of the assembly sizes were big which takes some time to load the Silverlight application on client side. As by default, the XAP file embedded all the assemblies in itself. But you can change that option by “Reduce XAP size by using application library caching” option from Project properties of your Silverlight project.

By doing this a compressed version of all the assemblies downloaded on client side and cached and next time if you reload the application it will not download all the assemblies again but used the cached version.

When you enable this check all the assemblies that are referenced in the Silverlight project got compressed and added in the ClientBin folder.

After doing this, when I checked the XAP file size I got really happy.

Before compression

After compression

 

Bridging data between ASP.Net and Silverlight

A task comes up to me in which I have to develop a private chat application for some product. I did some research on the XMPP protocol used by Facebook, Google etc. XMPP is a powerful protocol for public chat applications where thousands of users connect with each other. It has a separate XMPP server which listens to request and respond on it. There are also bunch of free XMPP servers available in the market.

Our goal is to provide a private chat where mid amount of users coordinate with particular resources time to time and the message format is not just simple like normal chat applications. We need to pass some advanced set of information to the recipient depending on which chat mode he has chosen. Then I chose WCF Duplex messaging where I can put all the business logic and intercept messages easily.

In order to make a chat application just like Facebook which have panel on the right and load chat popups that remains on the page I have to used Silverlight and ASP.Net and provide a special bridging between them. The reason of using Silverlight is that the ASP.Net doesn’t work with WCF Duplex Messaging because the framework of ASP.Net is request/response, whereas the Silverlight client is downloaded at client side and on each connection with WCF Service, service can send data back to client using default port 80.

I will not share how WCF Duplex messaging works, as I already published one article before on that but I will highlight the scenarios that can be implemented using very easy and simple code snippet provided to accomplish a bridging between ASP.Net and Silverlight.

Calling JavaScript function from Silverlight

string username = “Ovais”;

HtmlPage.Window.Invoke(“JSFunction”, username);

    

JSFunction is the javascript function implemented on the page where the Silverlight control is hosted. You can also pass the complete class object using Invoke method but that class object should be annotated by [ScriptableType()]attribute

[ScriptableType()]

public
class
ChatInfo

{

public
string UserName { get; set; }

public
int UserType {get; set; }

}

 

ChatInfo cInfo = new
ChatInfo() { UserName = “Ovais”, UserType = 1 };

HtmlPage.Window.Invoke(“JSFunction”, cInfo);

 

Getting Data in Silverlight from ASP.Net

In Silverlight you can read the HTML DOM using HTMLPage.Document object

HtmlPage.Document.GetElementById(“hiddenField1”).GetAttribute(“value”).ToString();

 

Using above two scenarios I succeeded passing data between both.

 

Happy coding!

 

Enabling Lazy Loading in Entity Framework Code First Model

In Entity Framework you can configure several attributes for your Database Context class. In this article I will tell you what Is Lazy Loading and how you can leverage this feature in Code First Model.

Lazy Loading is a feature through which the Code First engine loads the navigation objects that belongs to the parent entity. For e.g. If there is a Person Entity and Person belongs to particular Department. Now when you load the Person retrieve the person object it will load the Department object values as well through which you can easily navigate to its properties and display those on forms or anywhere.

In order to enable Lazy Loading you can enable the properties values under your context constructor as follows.


public DemoContext()

{


this.Configuration.LazyLoadingEnabled = true;


this.Configuration.ProxyCreationEnabled = true;

}

 

One important point, lazy loading will only work if the ProxyCreationEnabled is enabled and the Navigation property of entity is virtual.

 


public
class
Person

{


public
Int32 Id { set; get; }


public
String Name { set; get; }

 


public
virtual
Department Department { get; set; }


public
Int32 DepartmentId { set; get; }

 


public
string Gender { set; get; }

}

 


public
class
Department

{


public
Int32 Id { set; get; }


public
String DepartmentName { set; get; }


public
virtual
ICollection<Person> Persons { set; get; }

}

 

Now, let suppose person table and department table have few records stored. When you read the Person using context.ToList () or any other linq function it will automatically load the department objects as well.

Develop a function that returns the list.

public
Person GetPerson(int id)

{


DemoContext context = new
DemoContext();

{


var items = context.Persons.Where(i => i.Id == 1);


return items;

}

}

 

Now, by adding a watch on Items you can see that you will get corresponding Department values i.e. DepartmentName and Id as well.


Therefore, Lazy loading helps developer to retrieve the child objects rather making joins in Linq query and automatically do the join part.

Happy Coding!

Enabling Transactions in WCF

Transaction plays an important role in any business application that involved CRUD operations. To implement transactions, we utilize TransactionScope class that automatically manages transactions and detect the scope of the transaction. You can apply TransactionScope on a block of code and regardless of how many WCF services instances you have opened or operation contracts you are calling will be carried on the scope of that transaction. For example, if you are calling three services methods and third one fails to complete the operation, transaction will be rolled back unless it’s outside the boundary of a TransactionScope.

WCF supports transaction on following bindings.

  1. WSHttpBinding
  2. NetTcpBinding
  3. NetNamedPipeBinding
  4. WSDualHttpBinding
  5. WSFederationHttpBinding

While developing a Service Contract you have to specify the TransactionFlow attribute on each Operation Contracts that requires a Transaction to be handled. In the below code snippet there are two methods one which submit employee master information and the other that submits employee details. As both require transaction so I have specified TransactionFlow attribute on both of them.

[OperationContract]

[TransactionFlow(TransactionFlowOption.Allowed)]


void CreateEmployee(Common.DataContracts.Employee employee);

[OperationContract]

[TransactionFlow(TransactionFlowOption.Allowed)]


void SubmitEmployeeDetails(EmployeeDetails employeeDetails);

There are following flow options in the TransactionFlow attribute.

TransactionFlowOption. Allowed : Transaction can be flowed.

TransactionFlowOption.Mandatory : Transaction must be flowed.

TransactionFlowOption.NotAllowed : Transaction should not be flowed. This is default.

Next, implement the service and specify OperationBehavior attribute on each method. You can specify the TransactionScopeRequired property as true or false.

[OperationBehavior(TransactionScopeRequired= true)]

public void CreateEmployee(Common.DataContracts.Employee employee){

}

Now enable the Transaction on the binding itself. Open your web.config file and specify the transactionflow = true as follows

<wsHttpBinding>

<binding
name=TransactionalBind
transactionFlow=true/> </wsHttpBinding>

Now add service reference and consume the service. While calling CreateEmployee and SubmitEmployeeDetails method you have to put them in the TransactionScope block and if any of the method fails, the transaction will be rollback.

using (TransactionScope scope = new
TransactionScope())

{

try

{

Services.EmployeeService.EmployeeServiceClient()

clientobj = new Services.EmployeeService.EmployeeServiceClient();

clientobj.CreateEmployee(employeeObj);

clientobj.SubmitEmployeeDetails(employeeObjDetails);

scope.Complete();

}

catch (Exception ex)

{

scope.Dispose();

}

}

Happy programming!

Basic Introduction about T4 Templates & How to customize them for ASP.NET MVC Project

In ASP.Net MVC 3 you can easily generate views from predefined scaffolding templates provided for Create, Edit, List, Delete and Details views out of the box which seems quite riveting. Actually, there are some *.tt template files (known as T4 templates) stored at following path C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\ItemTemplates\CSharp\Web that contains the basic structure and page layout for these views and based on those templates it generates the Create, Edit, Delete, List, Details and Empty .cshtml or .aspx files depends on which project language you have chosen for ASP.Net MVC project.

In this post I will discuss about T4 templates and how we can customize by taking a simple example.

What is T4

T4 stands for Text Template Transformation Toolkit. T4 generates text based on Text based template files, Template is a combination of text and control logic that you can define using C# or VB.net. Transformation actually executes the code written in template and brings out a final output whereas the Toolkit contains some assemblies leverage to produce the desire output file.

Now, let’s quickly open the sample Create.tt file to see what it looks like and how we can customize. When you open the file you can see directives

<#@ template language=”C#” HostSpecific=”True” #>

<#@ output extension=”.cshtml” #>

language specifies which language we are using either C# or VB.net and HostSpecific =”True” used only with custom hosts. If you set the value of parameter to true, you can access a property called Host in your text template. The property is a reference to the object that hosts the engine. At last, the output extension tells the extension in which the new file this will be generated.

T4 contains 4 types of blocks

  • Expression block

    Used as <#= expression #>, we can write C# or VB.net code but don’t use semi-colon at the end of statement

  • Statement block

    Used as <# code…. #>, define any C# or VB.net code and initialize variables, define loops etc. Here we have to specify semi-colon at the end of the code statement just like as we program in a class file.

  • Class feature block

    Used as <#+ code… #>, define methods, classes, properties and constants and can we called from anywhere within the template file. For example, we can create a function that perform some calculation based on the parameters passed and return a Boolean through which we can handle the UI designing.

Below is the actual page content that dynamically generates the page based on the model attached to it.

@using (Html.BeginForm()) {

@Html.ValidationSummary(true)

<fieldset>

<legend><#= mvcHost.ViewDataType.Name #></legend>

<#

foreach (ModelProperty property in GetModelProperties(mvcHost.ViewDataType)) {

if (!property.IsPrimaryKey && !property.IsReadOnly && property.Scaffold) {

#>

<div class=”editor-label”>

<#

if (property.IsForeignKey) {

#>

@Html.LabelFor(model => model.<#= property.Name #>, “<#= property.AssociationName #>”)

<#

} else {

#>

@Html.LabelFor(model => model.<#= property.Name #>)

<#

}

#>

</div>

<div class=”editor-field”>

<#

if (property.IsForeignKey) {

#>

@Html.DropDownList(“<#= property.Name #>”, String.Empty)

<#

} else {

#>

@Html.EditorFor(model => model.<#= property.Name #>)

<#

}

#>

@Html.ValidationMessageFor(model => model.<#= property.Name #>)

</div>

<#

}

}

#>

<p>

<input type=”submit” value=”Create” />

</p>

</fieldset>

}

<div>

@Html.ActionLink(“Back to List of Main Page”, “Index”)

</div>

In the above mentioned code there is if statement that checks whether the property is a foreign key or not and based on that it generates a drop down code otherwise an input control.

Let’s create a sample application in ASP.Net MVC 3 and check it out by customizing a Create T4 template.

  1. Create a sample project in ASP.Net MVC3 in Visual Studio.
  2. Create a model class for Person and Designation. Person record contains some basic information and Designation holds the list of designations. Below is the Code First model Approach using Entity Framework ver. 4.3.1.


    public
    class
    Person    

    {


    public
    long PersonId { set; get; }


    public
    String FirstName { set; get; }


    public
    String LastName { set; get; }


    public
    String EmailAddress { set; get; }


    public
    String Phone { set; get; }


    public
    long DesignationId { set; get; }


    public
    virtual
    Designation Designation { set; get; }

    }


    public
    class
    Designation

    {


    public
    long DesignationId { set; get; }


    public
    String DesignationName { set; get; }


    public
    virtual
    ICollection<Person> Persons { get; set; }

    }

  3. Create a DBContext class and define DBSet for these entities.

public
class
DBContext : System.Data.Entity.DbContext, IDisposable

{


public
DbSet<Person> Persons { get; set; }


public
DbSet<Designation> Designations { set; get; }

}

  1. Now create a Person controller selecting Controller with read/write actions and select Person as a Model class and DB Context as you Database Context class.

  1. Now if you open the Create.cshtml file you will see a drop down list for designation. As in the template file there was a foreign key check. If you run the application form will be shown as below.

  1. Now let’s change a drop down to list box in the Create.tt file.

    <div class=”editor-field”>

    <#

    if (property.IsForeignKey) {

    #>


    @Html.ListBox(“<#= property.Name #>”)

    <#

    } else {

    #>

    Is not a foreign key baba: <#= property.IsForeignKey #> : @Html.EditorFor(model => model.<#= property.Name #>)

    <#

    }

    #>

    @Html.ValidationMessageFor(model => model.<#= property.Name #>)

    </div>

  1. Delete the previous controller and generate it again. It will generate a ListBox as specified in a tt file.

This was the simple example showing how developers can modify existing templates based on their needs and reduce development time. Hope this helps!