Microsoft etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Microsoft etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

Pazartesi, Mart 13, 2017

Advanced Natural Language Processing Tools for Bot Makers – LUIS, Wit.ai, Api.ai and others


This article there have been some significant market updates which need to be considered. Google bought Api.ai and also released their own home-baked Cloud Natural Language API, Amazon introduced Amazon Lex – conversational API and Wit.ai is updating their Stories and making them even better.

Recent announcements of a bot framework for Skype from Microsoft and a Messaging Platform for Messenger from Facebook have transformed chat through a new platform. More and more developers are coming up with the idea to make their own bot for Slack, Telegram, Skype, Kik, Messenger and, probably, several other platforms that might pop up over the next couple of months.

NLP for bots

Thus, we have a rising interest in the under-explored potential of making smart bots with AI capabilities and conversational human-computer interaction as the main paradigm.

In order to build a good conversational interface we need to look beyond a simple search by a substring or regular expressions that we usually use while dealing with strings.

The task of understanding spoken language and free text conversation in plain English is not as straightforward as it might seem at first glance.

Below we look at a possible dialogue structure and demonstrate how to understand the concepts behind advanced natural language processing tools. We also focus on the platforms that we can use for our bots today, including the API – LUIS from Microsoft, Wit.ai from Facebook, Api.ai from Assistant team Google, Watson from IBM and Alexa Skill Set, and Lex from Amazon.

Ready to build a conversational bot for your business, but confused with the variety of platforms?

A Dialogue Example

Let’s look at the ways we can ask a system to find ‘asian food near me.’ The variety of search phrases and utterances could look similar to this:

  • Asian food near me please
  • Food delivery place not far from here
  • Thai restaurants in my neighborhood
  • Indian restaurant nearby
  • Sushi express places please
  • Places with asian cuisine
  • Etc.

But if we are curious enough, we can also ask Google Keyword Planner for other related ideas and extend our list by about 800 phrases related to the search term “asian food near me”. We use Keyword Planner for such tasks here because it is a great source of aggregated searches that users regularly perform in Google.

Google Keywords ideas to for extending the bot dictionary

Google Keywords ideas for extending the bot dictionary

Of course, not all of this is directly related to the original search intent, asian food near me. Let’s say, however, that we want to create a curated list of Asian Food places; in this case we can see that the results are still highly relevant to the service that we want to provide to the users.

So therefore we can try to steer the conversation towards the desired ‘asian food’ topic with the help of questions and suggestions from the bot.

Consider the next dialogue examples and suggestions of ways to direct the conversation:

Examples of dialogues with a conversational bot

Examples of dialogues with a conversational bot

From the example above we see how a broad variety of utterances can be employed by the user for the purpose of finding food.

Also notice how users can say Yes and No during the dialogue for confirmation or decline of the suggested option.

Yes/No answers variations

Yes/No answers variations

It is clear that chatbots need some way of understanding the language and conversational phrases that are more sophisticated than just a simple text search by phrase or even regular expressions.

Dialogue Structure as NLP engineers see it

From the example above we can see that each expression from the users has the intent to take some action.

An Intent is the core concept in building the conversational UI in chat systems, so the first thing that we can do with the incoming message from the user is to understand its Intent. This means mapping a phrase to a specific action that we can really provide.

Along with the Intent, it’s necessary to extract the parameters of actions from the phrase. In the previous example with ‘asian food’, the words ‘nearby’ or ‘near me’ correspond to the current location of the user.

Parameters, also called entities, often belong to a particular type. Examples of entity types that are commonly supported in language understanding systems are:

  • Location
  • Datetime
  • Number
  • Enumeration (predefined list of named things)
  • Contact
  • Distance
  • Duration

Here are the basic representations of the Intent, Entities and Parameters, as well as Sessions and Contexts which we will discuss later.

Dialogue structure for bots interface

Dialogue structure for bots interface

A Session usually represents one conversation from beginning to end. An example of one session is when you order a flight from your starting point: ‘I need a flight to London’ (the intent), then through subsequent interactions (questions and answers) you get the information about a booked flight and finish the interaction.

For storing the intermediate states and parameters from previous expressions during the dialogue we usually use Context. We can think about context as a shared basket that we carry through the whole session and use as short term memory. For example, during the flight booking chat, we can store the intent BookFlight in a context and subsequently add other parameters (like FlightDates, FlightDestination, NumberOfStops or MinMaxPrice) from the conversation once we get them from the user.

Unlike a session we can have many contexts during one conversation that nest into one another. Let’s say, after the user expression that represents the BookFlight intent, we started a new context, BookFlightContext, which indicates that we are currently collecting all parameters needed for the booking.

After the question about flight dates, the user decides to request info from the calendar, thus expressing a new intent CalendarEvents, and starting a new context, CalendarEventsContext, that saves the state of user interaction during the dialogue about events in a calendar. The user can even decide to reschedule several events and write a short email to involved parties with apologies and a reason for rescheduling, thus creating another nested context object, NewEmailContext.

A nested context example in a branched dialogue

A nested context example in a branched dialogue

So some of the technical tasks of the chat bot app (or conversational agent) are:

  1. Understand the language in a plain text (or voice translated into text) as well as the Intent with Parameters.
  2. Process the Intent with Parameters and execute the next action to continue a dialogue with the user. (Result is a response or a subsequent question to continue the conversation by getting more data from the user and filling needed parameters in order to fulfill the action).
  3. Maintain the Context and its state with all parameters received during the single Session in order to get the required result to the user.

Next, we will look at how the available tools can help us with all of this.

Microsoft Language Understanding Intelligent Service (LUIS)

LUIS was introduced during this year’s Microsoft Build 2016 event in San Francisco, together with Microsoft Bot Framework and Skype Developer Platform, which can be used to create Skype Bots. In this article we leave aside Bot Framework and look at language understanding features from LUIS.

LUIS provides Entities that you can define and then teach to recognize a LUIS system from a free-text expression. There are also Hierarchical Entities that are helpful for recognizing different types or sub-groups. For instance, a FlightDate entity can have a ToDate and a FromDate which can be recognized separately.

Currently, there are limitations of up to 10 Entities of each type per application, which will be enough for a middle-size service.

LUIS training mode

LUIS training mode

Besides Intents and Entities, there is also the concept of Actions that can be triggered by the system once the Intent and all required parameters are present.

Moving closer to automatic language understanding and the acting upon completion of Intents with parameters, there is another feature called Action Fulfilment, which is currently present only in preview mode, but you can already play with it and plan for the future. The idea is that once we have an Intent the system can automatically execute predefined Channel Actions like GetCurrentWeather, GetNews or your own JsonRequest to an arbitrary API.

Dialogue support, which also presents only in a preview mode, can help us to organize the conversation and ask relevant questions to the user in order to fill in the missing parameters for the intent.

To train the model with different utterances, LUIS provides a Web interface where we can type an expression, see an output from the model, and make changes in labels or assign new intents. Additionally, LUIS stores all incoming expressions in the Logs section and provides semi-automatic learning features with Suggestion, where the system tries to predict the correct intents that are already present in the model.

LUIS Review training data mode

LUIS Review training data mode

Once we have the trained model, we can use the API to ask questions and receive intents, entities and actions with parameters for each expression as an input.

LUIS Example of API Response

LUIS Example of API Response

LUIS has the export/import feature for the trained model in a plain JSON with all expressions and markups for entities, which we can then repurpose in our code – or even substitute LUIS completely, if we decide later to build our own NLP engine.

Currently, LUIS is in beta and free to use for up to 100k requests per month and up to 5 requests per second for each account.

Next we will look at Wit.ai from Facebook.

Facebook Wit.ai Bot Engine

Wit.ai, an AI startup that aims to help developers with Natural Language Processing tasks through the API, was acquired by Facebook in January 2015. During the F8 conference in April, 2016, Facebook introduced a major update to their platform and rolled out their own version of Bot Engine that extends a previous intent-oriented approach to the story-oriented approach.

Wit.ai stories interface for dialogue definition

Wit.ai stories interface for dialogue definition

Building the conversation interfaces around story feels more natural and easier to follow than a separate intent string by the context variable. Under the hood, during the logic implementation, you still work extensively with the context and need to do all tasks required to maintain the conversation’s correct state.

Wit.ai dialogue example with intents, entities and a context

Wit.ai dialogue example with intents, entities and a context

In Wit.ai we can use Entities, Intents (it’s actually just a custom entity type here), Context and Actions concepts that together form the model based on Machine Learning, and statistics can be used later for understanding the language.

On the bot side, during the story definition, we can execute any action that we might need to fulfill the context, user action, and prepare data and/or states in the context. Effectively, the Wit.ai Converse API will resolve the user utterance and the given state into the next state/action of your system, thus giving you the tool to build a Finite State Machine that describes sequences of speech acts.

However, all actions are executed on our server, and Wit.ai just orchestrates the process and suggests the next call of state mutations based on the model that we’ve trained.

Everything, from understanding the user inputs to the training expressions and list of entities, is available through the extensive Wit.ai API.

Wit.ai Converse API response

Wit.ai Converse API response

Like other systems, Wit.ai provides a handy Inbox feature where you can access all incoming utterances from the users, and label them if they were not recognized correctly.

In one of the latest updates, Wit.ai introduced the chat UI for testing conversations so we can see steps that systems recognize, which helps during both the creation and the debugging of the model.

Wit.ai Chat UI for conversation testing

Wit.ai Chat UI for conversation testing

Wit.ai supports 50 different languages including English, Chinese, Japanese, Polish, Ukrainian and Russian.

Projects can be Open or Private, without any apparent limitations. Open projects can be forked and you can create you own version of the model on top of existing community projects.

The Wit.ai API is completely free with no limitations on request rates, thus it is a good choice for your next bot experiments.

Wit.ai is continuously pushing new features and capabilities. Since the release of the first version of this article they’ve make a better builder for the Stories and added support for Quick Replies, Branches (if/else) and Jumps in Stories which is great for describing complex flows.

Api.ai – conversational UX Platform

Api.ai was created by a team who had built a personal assistant app for major mobile platforms with speech and text-enabled conversations.

To give you a better understanding of how API is different from other platforms, here is the answer their CEO gave on Product Hunt:

Apiai-comment

Indeed, the service provides all the features you might expect from a decent conversational platform including support of Intents, Entities, Actions with parameters, Contexts, Speech to Text and Text to Speech capabilities, along with machine learning that works silently and trains your model.

Everything starts from Agents that represent the model and rules for your application.

The basic interaction model (image from API.ai docs)

The basic interaction model (image from API.ai docs)

The interesting thing is that API.ai has built-in domains of knowledge (Intents with Entities and even suggested Replies) on topics like small talk, weather, apps and even wisdom. It means that your new Agent on the system can recognize these Intents without any additional training – and even provide you with the response text which you can use as the next thing your bot will say. There are up to 35 different domains with full English support and partial support for the other six languages.

When you create an Intent, you directly define which Context the Intent should expect and produce as a result. You can also define several speech responses which an agent will return to your app through the API, so you don’t even need to store such variations in your app.

Intent creation view in Api.ai

Intent creation view in Api.ai

Api.ai provides integrations with different bot platforms including Slack, Facebook Messenger, Kik, Alexa and Cortana.

For example, you can build the conversational flow completely on the platform and then deploy it automatically on Heroku, or use a pre-built Docker container with the app.

There is also an embedded integration mode available so you can have an agent that works without connection to the internet and is independent from any API. Just think about use cases like embedded hiking assistants or in-car assistants.

Api.ai looks like a decent solution that you can use for building sophisticated conversational interfaces. Like LUIS-beta from Microsoft or Wit.ai from Facebook, it’s Free with a limitation in bandwidth and speech recognition feature, though Preferred plan without limitation is also available by request.

Well, Google have bought Api.ai since the first version of this article. Good for the founders, but this means the community has lost the powerful independent NLP service, although a couple of other startups are emerging from the stealth mode.

Amazon Alexa Skill Set

It only works with Amazon Alexa. At first glance, this looks like the simplest language processing algorithm available among all other systems, but it’s deployed, tested and exposed to more than 3 million Amazon Alexa users who are already using conversational interfaces on a daily basis.

Setting up Alexa Skills

Setting up Alexa Skills

With Amazon Alexa Skills Kit you can define Intents and Entities for your task. Alexa system recognizes an intent correctly with variations in words only when you provide every possible example of expressions that could exactly match how users might say it to Alexa. It feels like they are still working on their own version of machine learning in order to simplify the work needed for model training.

The great thing is that a whole new skill for Alexa could easily be built with AWS Lambda functions, that seamlessly integrates with the Alexa Skills Kit.

Anyway, Amazon Alexa Skills Kit is an outstanding system that you should keep in mind,following their development, because Amazon is currently a leading household platform for conversations and custom bot integrations, which they are aggressively pushing forward with new device offerings and features.

Amazon revealed Amazon Lex – a conversational interface API with NLP features and tight integration to Amazon services such as Lambda, Dynamo DB, SNS/SES and others. We’ll look into Amazon Lex internals once it becomes available.

Amazon Lex Diagram

Build an Amazon Lex bot that allows patients to book appointments. Source: Amazon

IBM Watson Developer Cloud Services

You probably remember the famous IBM Watson’s game when it won against two humans on the TV quiz show “Jeopardy” in 2011. So the good news is that IBM moved the technology behind the Watson into the cloud and released the set of API that you can use in your own conversational applications.

The API set includes language understanding offerings from a natural language classifier to concept insights and dialogue processing. There are a lot of building blocks that you can use in your application, but you probably will spend a fair amount of time integrating them into one solution.

IBM Watson list of services

IBM Watson list of services

We’ve used IBM Alchemy Language for sentiment analysis and keywords extraction for our experiments and it worked well. We think that IBM’s solution is the ideal choice for enterprises that want to be 100% sure of their API provider.

For a recent IBM Watson demonstration you can watch a fireside chat with Dr. John Kelly, who leads the Watson team at IBM, at TechCrunch Disrupt 2015 in San Francisco.

IBM Watson is, however, a costly solution and you can expect to pay up to $0.02 per API call in Dialogue API, so it may be too expensive to experiment with in building bots for Facebook Messenger when you still don’t have a working business model.

The full list of available API’s from IBM Watson Developer Cloud available here.

Ready to build a conversational bot for your business, but confused with the variety of platforms? Let’s talk!

Conclusion

In this article, we have seen that there are various systems available for building conversational interfaces.

Our personal preference goes to Wit.ai from Facebook and LUIS from Microsoft, as they provide all the necessary elements for building conversations and they are free (at least for now), so you don’t have to worry about the price.

Anyway, we would recommend you store all data needed for your model in a structured way in your own code repository. This means that later you can retrain the model from scratch, or even change the language understanding provider if needed. You just don’t want to be in a situation when a company shuts down their service and you are completely unprepared. Do you remember Parse?

For the end-to-end solutions that requires less code, we think Api.ai is the way to go. This is also a good option if you need embedded capabilities, avoiding dependence on an internet connection. We are also often using Chatfuel as it’s an easy to build builder of conversational flow with a powerfull JSON API integrations.

Alexa Skills Kit is proprietary for Amazon Echo devices, therefore you can’t use it with arbitrary bots at Slack or Facebook Messenger for language processing, but it is ideal for smart home bots that augment your kitchen or living room environment, and which are built specifically for Alexa. Luckily Amazon Lex will soon be available to the public, so it could pose a great alternative, especially if your infrastructure is already tapped into the AWS ecosystem.

IBM Watson will work smoothly in an enterprise environment when you need to feed large amounts of data, you have a decent budget and you want to have a reliable and proven service provider behind you.

Generally speaking, we expect to see many more platforms and API services for language understanding tasks in 2016, because the field is just beginning to heat up, with the major platforms newly announcing their bot platforms and frameworks.

Google have launched their own NLP service, Cloud Natural Language API, which is packed with text analytics, content classifications & relationship graphs, and deep learning models that you can use for your chatbot needs. We’ll review Google’s offering in a separate article.

Google’s Parsey McParseface SyntaxNet model.

Google’s Parsey McParseface SyntaxNet model.

Stay tuned and happy chatbot building.

Building our own bot

This article was written as part of our own challenge to build a smart bot with AI capabilities that can help people understand how to build a mobile app, give useful advice and provide an estimation of development and design costs.

Cumartesi, Mart 23, 2013

Teknoloji Seçimi - Kurumsal Projeler (SAP, Microsoft, vd…)

Merhaba,

 

Bir önceki yazıda firmaların uygulama seçiminde dikkat ettiği kararları ve organizasyonel yapılanma hakkında kısa kısa bilgiler vermeye çalışmıştık. Bu yazıda ise kalıcı projelerin oluşturulması ve stratejik kararların verilmesi anında yaşanan süreçleri irdeleyeceğiz.

 

BT insanlarının kariyerlerinin en başlarında yaşadıkları bir ironi vardır. Hangi uygulama geliştirme platformunu kullanmalıyım? Sen Java ‘cısın ben .Net ‘çiyim, o Delphi ‘ci. Bunlardan hangisi daha iyi. Hangisinde kendimi geliştirmeliyim. Yoksa ben uygulama geliştiremiyor muyum? Peki analist mi olmalıyım? Yoksa veri tabanı yöneticisi mi? Bu sorular sürekli geldi geçti başımızdan… Öncelikle dikkat etmemiz gereken konu hepsinin en sonunda aynı noktaya ve aynı amaca hizmet ettiğini görmek. Bir sonraki süreçte ise proje, yaşam ve stratejilere bağlı olarak farklı teknolojiler ve farklı firmaların ürünlerini kullanmamız gerekebilir. Eğer fanatik bir teknoloji sever iseniz içinizde yanan ateşi söndürerek işinizi yapmaya bakın.

İçten yanan ateşe en güzel örneği kendimden verebilirim. Sektöre başladığımdan beri elimden geldiğinde en yeni teknolojiyi geliştirmiş / geliştirtmiş olduğum projeler tercih etmeye çalıştım. Ancak elimden geldiğince dememin bir sebebi var. Kendim için gariptir ki dahil oldğum projelerin neredeyse tamamı .Net 1.0 ‘da ya da asp ‘de hazırlanmış olan projelerin yeni teknolojiye (.Net 2.0 ne kadar yeniyse artık… ( Daha yeni teknolojilerede geçiyoruz bu arada. ) Smile ) taşıma ve sürdürebilirlik projeleri oldu. Burada bir projeyi .Net 3.5 ya da .Net 4.0 var iken .Net 2.0 yapacaksın demeleri en başlarda içsel bir huzursuzluğa yol açsa da zamanla kurumsal kimliklerden kaynaklı olarak böyle stratejiler yapıldığı gözlemlenebiliyor. Farklı firmalarda da buna benzer konular yaşandıkça artık insan alışıyor ve uyum sağlayarak iyi en iyi şekilde yapmaya çalışıyor.

 

Herhangi bir firmanın proje grubunda yer aldığınızda öncelikli olarak göreceğimiz ilk proje CRM uygulaması olacaktır. Ayrıca sürekli olarak bu uygulamayı geliştirmenin ve iyileştirmenin çabaları ve organizasyonel yapılandırmaları yapılır. Genellikle CRM uygulamaları Mıcrosoft .Net Framework üzerinde web ya da desktop application olarak hazırlanmış projelerdir. Eğer ki Desktop application ise Citrix üzerinde çalıştırmanın yollarına ya da web uygulaması ile yeniden yapılandırılması amaçlanır. Bu iki adımda gerçekleşti ise günümüzde sağlamış olduğu standartlık ve stabilizasyonu sebebi ile uygulamayı SAP üzerine taşımak adımı yaşanmaya başlıyor. Eğer ki Intranet uygulamaları var ise bu uygulamalarda Sharepoint server üzerinde tasarlanmaya çalışıyor.

 

Olayın bir de çok farklı bir boyutu var. Neredeyse Microsoft ile anlaşması olan firmaların büyük çoğunluğunda Sharepoint server kurulu ve döküman yönetim sistemi olarak kullanıldığı gözlemlenir. Ancak crawl kurgulanmadığı için arama kriterlerinden öte sadece saklama alanı olarak kullanılır. Zamanla bu uygulamaların daha efektif kullanılması için planlama yapılır ve geliştirilir.

 

Uygulamaların geliştirilmesi ve sürdürülebilmesi için kararlar alınmalıdır ve gerçekleştirilebilmelidir.

 

Günümğz polüler seçimlerini dikkat aldığımızda

  • CRM uygulamaları için Dynamics CRM ve SAP kullanımı
  • Portal ve Intranet uygulamalarında Sharepoint kullanımı
  • Web uygulamalarında MVC Framework ‘I kullanma
  • Desktop application için WPF ve XAML form kullanımı
  • Azure servislerinin kullanımı
  • Santral sistemlerinde Avaya kullanımı
  • ve tabiki sosyal medyanın yüksek olan ve yükselme potansiyeli daha fazla olan gücü
    şeklinde sırayabiliriz.
Tekrardan görüşmek üzere…

Pazartesi, Ekim 18, 2010

Yazgeliştir Gönüllüleri Toplantısı

Türkiye’de yazılım geliştirme alanında çalışanların paylaşım noktası olan Yazgeliştir’i takip eden herkesi 23 Ekim Cumartesi günü düzenleyeceğimiz Yazgeliştir Gönüllüleri etkinliğine bekliyoruz. Bu etkinlikte Yazgeliştir yönetimi ve editörleri ile tanışıp, Yazgeliştir ile ilgili son gelişmeler ve gelecek planlarından haberdar olacaksınız. Ayrıca Yazgeliştir ekibi olarak görüş ve önerilerinizi dinliyor olacağız. Tüm bunların yanısıra etkinlikte yazılım geliştirme alanındaki son yenilikler içerikli bir sunum da olacak. Microsoft İstanbul ofisinde saat 13:00’te başlayacak etkinliğimizin program detaylarını aşağıda bulabilirsiniz:

Tarih:
23 Ekim 2010 Cumartesi, 13:00 – 17:00

Program:
13:00 – 14:00
Yazgeliştir yönetimi ile tanışma
14:00 – 15:00 Son gelişmeler ve 2011 planları
15:00 – 15:45 Açık tartışma
16:00 – 16:45 Yazılımcılar İçin Yenilikler – Tamer Öz

Yer:
Microsoft İstanbul Ofisi
Bellevue Residence Levent Mahallesi
Aydın Sokak. No:7 Levent,
34340 İstanbul/Türkiye

Pazartesi, Nisan 12, 2010

Visual Studio 2010 – RTM

Visual Studio 2010 çıktı.

Uzun bir gelişme sürecinin ardından Visual Studio 2010 resmi olarak satışa sunuldu.Visual Studio 2010

IDE üzerinde WPF ‘in nimetlerinden yararlanılarak yapılan değişiklikler, WWF ‘in tasarımın ve akış tiplerinin yenilenmesi, F# dilinin entegre edilmesi, MVC 2 ile beraber gelmesi ve diğer bir çok özelliği ile bugün VS2010 çıkmış bulunuyor. Deneme sürümünü indirip kurmak isteyenler aşağıda verecek olduğum linkten yararlanabilirler. Almak isteyenler için ise Visual Studio 2010 Ultimate satış fiyatı $11850. :)

http://www.microsoft.com/visualstudio/en-us/download

Salı, Ekim 20, 2009

MSDN Online - Tasarımı yenilendi.

Microsoft teknolojileri ile uygulama geliştiripte uğramamış olmanızın çok düşük olduğu bir sitedir MSDN Online. İşte bu güzel sitenin tasarımı yıllar sonra değişti. Sizlerde daha zengin içerik, daha fazla dil desteği ve daha canlı renkler ile bu güzel siteyi takip etmek isterseniz www.msdn.com adresinden yararlanabilirsiniz.

Pazartesi, Ekim 19, 2009

Microsoft Security Essentials



Microsoft'un ücretsiz olarak sunduğu Security Essentials adlı antivirüs programı, 1.0.1611 sürümü ile yayınlandı. Programı, aşağıdaki adresten indirebilirsiniz:
http://www.microsoft.com/security_essentials/

Not: Windows 7 ile oldukça uyumlu çalışmaktadır.

Pazartesi, Temmuz 27, 2009

Microsoft - Kariyer İmkanları

MicrosoftJobPicture Microsoft ta çalışmak isteyenler nereden başvuracaklarını ilk etapta bilemezler. Bu sebepten ötürü sizlere gerekli olan web sitesini ve aranılan özellikleri yazacağım.

İlk olarak web sitesini verelim. https://careers.microsoft.com/ adresi üzerinden açık olan pozisyonlara ve gerekli özelliklere erişebilirsiniz.

Şimdi de genel olarak aranılan özelliklere değinelim.

  • Üniversitelerin ilgili bölümlerinde okumak ya da mezun olmak
  • 10 yıl veya üzerinde uzmanlık alanınızda tecrübenizin olması
  • Başvurduğunuz pozisyonda 3 yılın üzerinde tecrübeniz olması
  • Proje yönetim metodoloilerine bağlı disipline yapıda çalışabilmek
  • Çok iyi düzeyde ingilizce bilgisine sahip olmak.
  • Farklı çalışma saatlerinde çalışabilmek
  • Sunum yeteneğine sahip olmak
  • Çalışırken eğlenebilmek
  • Teknolojik anlamda geliştirilecek yeniliklere çok hızlı bir şekilde uyum sağlayıp onların üzerinde her türlü işlemi yapabilir duruma gelmek.
  • İnsan yönetimi konusunda 5 yılın üzerinde tecrübeye sahip olmak

Genel olarak aranan özellikler bu şekildedir. Ayrıca ilgili pozisyonlara göre de bu seçenekler artmaktadır. Peki diğer sosyal olanaklar nasıl?

  • 6 hafta yıllık izin.
  • Sosyal aktiviteler
  • Spor kulüplerine üyelik
  • Yemek olanakları
  • Yaşam sigortası
  • Devlet yaşam sigortası gibi

Bu tür olanaklar ile dünya üzerinde yer alan Microsoft ofislerinde çalışabilme olanağınız vardır. Yukarıda bahsetmiş olduğum adreste yer alan iş ilanlarından herhangi birini seçtikten sonra kendinize uygun görüyorsanız başvurunuzu yapıyorsunuz. Sonrasında standart işe alım süreçleri tamamlandığında artık sizde bir Microsoft çalışanı oluyorsunuz. (Benim de hayalim o :) )

Umarım bir gün herkes istediği meslekte ve iş yerinde çalışabilir…

Herkese iyi günler diliyorum. Umarım yararlı olabilmiştir.

Pazar, Temmuz 12, 2009

Asp.Net MVC Framework - Master Pages Kullanımı - II

Asp.Net MVC Framework ile bugüne kadar bir çok konuya değinme şansı bulduk ve temel kavramlarını rahatlıkla yapabilir duruma geldik. Görsel olarak uygulamalarımızı daha da kuvvetli duruma getirebilmek için bir önceki MVC Framework yazımızda Master Page 'i nasıl kullanabileceğimize değinmiştik. Peki bu noktada aklımıza bir kaç soru takılıyor. Eğer tasarımsal öğelerini rahatlıkla düzenleyebiliyorsak hazır şablonlar da olmalı ve onlar yardımı ile de düzenleyebiliriz şeklinde sorular gelmektedir. Bunun cevabı ise oldukça basittir. MVC ile geliştirilen uygulamalarda kullanılmak üzere oluşturulan tasarım galerisi sayfası mevcuttur. Buradan erişebilmemiz mümkün olacaktır.

Yazımızın girişinde de anlayacağınız gibi farklı tasarım şablonlarını uygulamalarımızda nasıl kullanabileceğimizi inceleye çalışacağız. Ama ilk olarak bu değişiklikleri uygulayabilmemiz için bir projeye ihtiyacımız vardır. Daha önceki yazılarımızdan yararlanarak hızlıca bir tane oluşturuyoruz.



İlk olarak yapmamız gereken yukarıda görmüş olduğumuz standart MVC Framework tasarımını düzenleyecek görsel şablonu seçmemiz gerekiyor. Bu işlemi gerçekleştirmek için MVC Framework galeri sitesine girmemiz gerekecektir. Sitemize http://www.asp.net/mvc/gallery/ adresinden ulaşabilmemiz mümkündür.



Yukarıda görmüş olduğunuz tasarımların dışında daha onlarca tasarım yer almaktadır. Bu tasarımlardan herhangi birini seçerek web sitemize uygulamayabilmemiz mümkündür. Beğendiğimiz herhangi bir tasarımı beğeniyoruz ve aşağıdaki işlemleri uygulamaya başlıyoruz.

1. Beğenmiş olduğumuz tasarımı bilgisayara indirebilmek için tasarımın hemen altında yer alan Download seçeneğine tıklıyoruz.
2. İndirmiş olduğunuz sıkıştırılmış dosyanın üzerinde sağ tıklama sonrası özelliklerine giriyoruz ve Unblock seçeneğine tıklıyoruz.



3. Tasarımı sıkıştırılmış dosyanın içerisinden çıkartıyoruz.
4. Çıkartmış olduğunuz dosyalar CS ve VB için oluşturulmuştur. Hangi programlama dili ile projenizi geliştiriyorsanız onun içeriğini kopyalıyorsunuz.
5.
Geliştirmekte olduğunuz MVC Framework web projesinin bilgisayarınızda olduğu klasöre gidiyorsunuz ve kopyalamış olduğunuz dosyaları yapıştırıyorsunuz ve benzer dosyaları değiştireyim mi diye soran ekranda evet seçeneğini seçiyoruz.



6. Artık projenizin tasarımı indirmiş olduğunuz tasarıma göre güncellenmiştir. Yapmanız gereken son işlem [YourProjectName] yazan yerleri kendi projenizin ismi ile değiştirmek olacaktır.



Yapılan işlemler sonucunda projenin almış olduğu görünüme bir göz atalım. Bakalım seçmiş olduğumuz tasarım hazırlanmış olan projenin üzerinde nasıl gözüktü.



Artık oldukça şık tasarıma sahip bir web sitesine sahibiz.

Şimdi eklemiş olduğumuz tasarımı bizlerde biraz daha düzenleyerek çok daha görsel bir görünüme getirelim. Örneğin düzenle, detaylar ve yeni oluştur yazılarını ikon olarak değiştirip çok daha anlaşılır bir görünüme kavuşturalım. bu işlemi gerçekleştirmek için yapmamız gereken ister bir tasarımcı tarafında oluşturulmuş olan ister internet üzerinden bulunmuş resimleri yazıların yerine kullanmak olacaktır.

Ekran üzerinde controller üzerinden gelen bilgilere göre işlemlere yönlendirirken Html.ActionLink() 'i kullanıyorduk. Fakat bu yöntem içerisine resim ekleyebilmemiz mümkün değildir. Aldığı parametreler Html.ActionLink("string","ActionStrign",RouteValue") şeklindedir. Projelerde kullanım şeklide aşağıdaki gibi olmaktadır.

<%= Html.ActionLink("Düzenle", "Edit", new { id=item.Id }) %>
|
<%= Html.ActionLink("Detaylar", "Details", new { id=item.Id })%>

Fakat bizim bu noktada yapmak istediğimiz proje eklenmiş ikonları detaylar ve düzenle bölümünde gösterirken linkleri de bu resimler üzerinde aktif olarak kullanılmasını isteyeceğiz. Tabii tekrar hatırlamak gerekirse bu işlemi Html.ActionLink() yardımı ile yapamıyoruz. Bunun için Url.Action() 'ı kullanırsak yapmak istediğimizi gerçekleştirebilir duruma geleceğiz. Çünkü bu parametre olarak Url.Action("ActionName","RouteValue") almaktadır. Bu durumda bizde <a href=""></a> taglarının arasında Url.Action() 'ı kullanırsak istemiş olduğumuz yönteme gelmiş olacağız. Ne gibi derseniz, web sayfalarında link vermek istediğimizde bizden linkin görünebilmesi için bir metin istemektedir. Bizler metin yerine resmi gösterirsek istediğimiz sonuca ulaşmış olacağız. Bu durumda yapmak istediklerimiz kod olarak görmek istersek aşağıdaki gibi bir görünüme sahip olacağız.

<td class="actions edit">
   <a href='<%= Url.Action("Edit", new {id=item.Id}) %>'>
      <
img src="../../Pictures/component_edit.gif" alt="Edit" width="20" height="20"/></a>
</td>
<td class="actions details">
   <a href='<%= Url.Action("Details", new {id=item.Id}) %>'>
      <
img src="../../Pictures/components.gif" alt="Detaylar" width="20" height="20"/></a>
</td>

Düşündüğümüz gibi controller dan gelen action ları link içerisinde tanımladık ve metin gireceğimiz bölümlere projenin içerisinde yer alan resim değerlerini vererek üzerine tıklandığında istenilen değerin detaylarına gitmesine olanak tanıdık. Peki yeni bir kayıt oluşturmak istediğimiz durumda ne gibi bir işlem yapmamız gerekmektedir. Ne gibi bir fark var diyebilirsiniz. Çok ufak bir fark bulunmaktadır. Bu da RouteValue parametresinin bulunmamasıdır. Fakat bizlere biliyoruz ki hem Html.ActionLink() 'te hem de Url.Action() RouteValue parametresi boş bırakılabilmektedir. Bu sebepten ötürüdür ki yeni bir kayıt oluşturma esnasında yukarıda vermiş olduğumuz kod parçasını olduğu gibi kullanmakla beraber yalnızca new{id=item.Id} parametresinin olduğu değeri silmemiz yeterli olacaktır. Yapmış olduğumuz işlemler sonrasında projemizin nasıl bir görünüme sahip olduğuna göz atmak gerekirse,



Oldukça hoş bir uygulamaya sahip olduk. Hem görsel açıdan hem de performans açısından başarılı bir uygulamamız oldu. Fakat değinmek istediğim bir nokta var. Eklemiş olduğumuz resimlerin boyutları oranında sayfanın açılmasında çok ufakta olsa bir yavaşlama gözlemlenmektedir. Bu açıdan resim eklerken boyutlarına mümkün oldukça dikkat ediniz.

Geldik bir MVC Framework yazımızın daha sonuna. Nelere değindiğimize kısaca göz atmak gerekirse, MVC Framework ile hazırlanan uygulamaların varsayılan tasarımının dışına çıkmak için Master Pages üzerinde yapabileceğimiz değişiklikleri bir önceki yazımızda inceledikten sonra bu yazımızda da MVC uygulamaları kullanılabilecek tasarımların yer aldığı galeriden yararlanarak seçmiş olduğumuz tasarımı kendi uygulamamız üzerinde nasıl kullanabileceğimize ve üzerinde düzenleme yapmak istediğimiz hangi adımları ve değişiklikleri yapmamız gerektiğini incelemeye çalıştık. Bir sonraki yazımızda görüşünceye dek, esenlikle kalın...

Umarım yararlı olabilmiştir.

Turhal Temizer
info@turhaltemizer.com

Çarşamba, Temmuz 08, 2009

Asp.Net MVC Framework - Master Pages Kavramı - I

Microsoft 'un web projelerini hazırlarken bizlere mimari tasarıları daha basit ve kullanışlı bir biçimde kullanmamızı sağlayan Asp.Net MVC Framework 'ü daha önceki yazılarımızda detaylı bir biçimde tanımaya çalıştık. Peki neler yapabiliyorduk. Son kullanıcıdan gelen istekler doğrultusunda başka bir sayfaya nasıl yönlendirebileceğimizi, Controller katmanı ile veri tabanı işlemlerini nasıl işleyip görsel sayfaya ileteceğimizi, model katmanı yardımı ile veri tabanı ile haberleşmelerin çok daha basit bir şekilde yapılabileceğini, veri tabanını aktif olarak kullandığımızda nasıl bir uygulama geliştirdiğimizi ve view sayfaları nasıl kolayca oluşturabileceğimizi detaylı olarak daha önceki yazılarımızda inceledik ve neler yapabileceğimizi gördük. Ayrıca uygulamalarımızda MVC tasarımını kullandığımızda daha önceden oldukça fazla uğraştığımız işlemleri ne kadar kolaylıkla yapabildiğimizi defalarca yapmış olduğumuz pratiklerde doğrulamış olduk. Bu yazımızda ise Asp.Net sayfalarında tasarım standardı açısından sıkça kullandığımız Master Pages kavramını MVC Framework 'te kullanım yapısını detaylı olarak inceliyor olacağız.

Asp.Net uygulamaların Master Page kullanmamızın sebebini kısaca hatırlayacak olursak. Benzer tarzda tasarım şablonu kullanacak olduğumuz sayfalarda tekrardan o tasarımsal öğeleri serverdan çağırıp sayfa üzerinde yüklenmemesini beklememek için oluşturulmuş başarılı bir yapıdır. Özellikle tasarım yapısı üzerinde herhangi bir değişiklik yok ise ve sadece içerikler değişecekse çok önemli bir tercih durumundadır. Aynı Asp.Net uygulamalarında olduğu gibi MVC uygulamalarında da Master Page kavramı önemli bir yer tutmaktadır. Varsayılan olan mavi bir tasarımı olan Master Page kullanılmaktadır. Peki biz bu tasarımı değil de kendi tasarımımızı Master Page 'e taşımak istersek neler yapmamız gerekir. Gelin hep birlikte bunu incelemeye çalışalım.

Her zaman olduğu gibi ilk olarak yapmamız gereken Visual Studio 2008 SP1 geliştirme ortamında bir Asp.Net MVC Framework Web uygulaması oluşturuyoruz. Proje dosyasının içerisinden ilk olarak varsayılan olarak oluşturulan Master Page 'in yerini bulalım.



MVC tasarımını dikkate alarak araştırmalarımızı yaptığımızda görsel öğelerin view katmanında olduğunu görürüz. Master Page her yerde kullanılacak bir içerik olduğu içinde view içerisinde Shared klasörünün içerisinde yer alır.

Biz uygulamamızda bu otomatik olarak oluşturulan Master Page 'i kullanmak yerine kendimize bir tane oluşturalım. Ama ilk olarak oluşturulmuş olan Site.Master 'ı siliyoruz. Sonrasında da Add- NewItem yolunu izleyerek web sitesine yeni bir Master Page ekliyoruz.



Master Page 'i sorunsuzca projeye ekledikten sonra nasıl bir içerik oluşturulacağının düşünülmesinin zamanı gelmiştir. Basit olması açısında içeriğe göre değiştirilebilir iki sütun ekleyelim. Bu değişen içerik eklemeyi Asp.Net 'ten de alışık olduğu gibi <asp:ContentPlaceHolder> yardımı ile yapacağız. İçeriği arttırdıktan sonra temel CSS ile Master Page 'in içerisine stil özellikleri de ekliyoruz ve bu yaptığımız işlemler sonrasında elimizdeki değişikler aşağıdaki gibi olacaktır.

View\Shared\Site.Master
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>

<!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><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>

   <style type="text/css">
      html
      {
         background-color:Gray;
      }

      .column
      {
         float:left;
         width:300px;
         border:solid 1px black;
         margin-right:10px;
         padding:5px;
         background-color:white;
         min-height:500px;
      }

   </style>
   <asp:ContentPlaceHolder ID="head" runat="server">
   </asp:ContentPlaceHolder>
</head>
<body>
   <h1>Sitem</h1>

   <div class="column">
      <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
      </asp:ContentPlaceHolder>
   </div>
   <div class="column">
      <asp:ContentPlaceHolder ID="ContentPlaceHolder2" runat="server">
      </asp:ContentPlaceHolder>
   </div>
</body>
</html>

Eklemiş olduğumuz içerik kontrollerini body 'nin içerisine <div> taglarının arasına yerleştiriyoruz. Ayrıca div taglarının sütün gibi hareket etmesi için stil özelliğine daha önceden hazırlamış olduğumuz column 'u tanımlıyoruz. Yaptığımız bu işlemler sonucunda Master Page 'in görünümü aşağıdaki gibi olacaktır.



Basit fakat bizlerin hazırlamış olduğu bir Master Page 'e sahip olduk.

Master Page 'i Kullanan View Sayfa Oluşturmak

Asp.Net uygulamalarında Master Page 'ten yararlanarak web sayfaları oluşturabilmemiz mümkündü. Bunun bize en büyük yararı oluşturmuş olduğumuz sayfalarda Master Pages üzerinde belirtmiş olduğumuz içerik kontrol alanlarının düzenlenebilmesi ve diğer taraflar üzerinde herhangi bir değişiklik yapmadan hazırlıyor olmamızdır. MVC Framework 'ten yararlanarak hazırlamış olduğumuz web sayfalarında da Master Page Asp.Net uygulamalarında olduğu gibi kullanılmaktadır.

View klasörünün içerisinde yer alan Home klasörünün üzerinde sağ tıklama sonrasında karşımıza gelen menüden Add - NewItem seçeneğine tıklayarak ekrandan MVC View Content Page i seçerek Master Page 'i kullanabileceği bir web sayfa oluşturmaya başlıyoruz.


Sayfa tipimizi seçip ekle dediğimizde hazırlamış olduğumuz Master Page 'ler den istediğimizi seçmek için bir ekran çıkacaktır.


Tamam dedikten sonra artık Master Page 'i kullanan bir web sayfası uygulamamızda oluşturulmuş olacaktır. Oluşturulan sayfanın arka plan kodları aşağıdaki gibi oluşturulmuştur.

View\Home\Index.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="ContentPlaceHolder2" runat="server">
</asp:Content>

Standart olarak projelere eklenmiş olan *.aspx sayfalardan farklı olarak HTML ve Body tagları yer almaktadır. Bu taglar Master Page de oluşturulduğu için yalnızca belirttiğimiz içerik kontrol alanları sayfada gözükmüştür ve sayfa içerisinde kullanıcılara göstermek istediğimiz içerikleri buralardan yayınlarız. Örnek olması açısında body taglarının içerisine eklemiş olduğumuz <asp:content> 'lerin içerisinde biraz değişiklik yaparak aldığımız sonuca hep birlikte çok atalım.

View\Home\Index.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
   İlk içerik kontrol alanı
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="ContentPlaceHolder2" runat="server">
   İkinci içerik kontrol alanı
</asp:Content>

Yaptığımız düzenleme sonrasında ekran değişikliğimiz aşağıdaki gibi olacaktır.



Yapılmış olan değişikler sonrasında web sayfamızın içeriği istediğimiz gibi olmuştur.

Master Page yardımı ile oluşturulan view sayfanın içeriğini düzenlemek

İlk olarak düzenleme yapağımız yer sayfamızın başlığı olacaktır. Oluşturmuş olduğumuz web sayfası internet tarayıcısında açıldığında pencerenin en üst kısmında yer alan bölümü düzenleyelim. Asp.Net ten ve diğer bütün web sayfası kodlama yapılarından alışık olduğumuz üzere title bölümünde belirtmemiz yeterli olacaktır.

Sayfamızın markup kod tarafında en üstte yer alan <Page> </Page> bölümün aralığının içerisinde yer alan title özelliğini değiştirerek sayfa başlığını sorunsuzca oluşturmuş oluruz.


Yapmış olduğumuz işlemi hazırlanmış olan Master Pages ile ilişkilendirerek tekrardan yapalım. Bu durumda ilk olarak oluşturulan Master Pages içerisine koyduğumuz içerik kontrol alanlarını hatırlamamız gerekir ve bir tane head bölümünün içerisine <asp:contentplaceholder> ekledik. Alana başlık, meta ve diğer birçok kriteri ekleyebilmemiz mümkündür. Bu özellikten yararlanarak aspx sayfasının içerisinde aşağıdaki değişiklikleri uyguluyoruz.

View\Home\Index.aspx
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
   <title>Başlık buraya yazılacak</title>
   <meta name="description" content="İçindekiler buraya" />
   <meta name="keywords" content="ana arama kriterleri buraya" />

</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
   İlk içerik kontrol alanı
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="ContentPlaceHolder2" runat="server">
   İkinci içerik kontrol alanı
</asp:Content>

Asp.Net uygulamaları ile uygulamadığımız tekniklerin birebir aynısıdır. Bu örneklerin bu kadar detaylı olarak gösterilmesinin sebebi Master Pages kavramının temel yapısının alışık olduğumuz Asp.Net Master Pages kavramından bir farkının olmadığını da göstermek amacıyladır. Yapmış olduğumuz işlemler sonrasında karşımıza gelen ekran görüntüsü aşağıdaki gibi olacaktır.



Yaptığımız işlemler sonucunda gayet başarılıyız. :)

Bu yazımızda Asp.Net MVC Framework ile hazırlanmış olan uygulamalarda Master Pages kavramını nasıl kullanabileceğimizi ve içerik düzenlemelerini nasıl kullanabileceğimizi detaylı bir biçimde incelemeye çalıştık. Bir sonraki MVC Framework yazımızda Master Pages kavramını incelemeye devam ederken veri tabanı işlemleri ile ilişkilerine de detaylı bir biçimde değineceğiz.

Umarım yararlı olabilmiştir.
info@turhaltemizer.com

Çarşamba, Haziran 03, 2009

Windows 7 - Çıkış Tarihi

Microsoft, işletim sistemi Windows 7'nin 22 Ekim'de satışa çıkarılacağını açıkladı.

Fazla tutulmayan Vista'nın yerini alacak olan sistem, PC yapımcılarına temmuz ayı sonunda verilmeye başlanacak. Windows 7 yüklü yeni bilgisayarlar, 22 Ekim'den itibaren satın alınabilecek veya yüklü işletim sistemleri yeni sisteme yükseltilebilecek.

Pazar, Mayıs 24, 2009

Asp.Net MVC Framework - View Kavramı

ASP.NET MVC Framework incelemeye View katmanı ile devam ediyoruz. Bu yazımızda Asp.Net MVC View, View Data ve HTML Helper kavramlarına değinip detaylı bir biçimde açıklamaya çalışıyor olacağız. Yazımızı tamamladığımızda MVC uygulamalarında View oluşturabilmeyi, Controller üzerinden gelen verileri view üzerinde gösterebilmeyi ve kendi html helper 'ımızı oluşturabilmeyi yapabiliyor olacağız.

Asp.Net MVC Framework - View 'ı Anlamak

Çok uzun zamandır web uygulamaları geliştiriciler tarafından hazırlanmakta ve kullanıcıların kullanımlarına sunulmaktadır. Asp.Net veya Active Server Page (ASP) kullanırken son kullanıcıdan gelen istekler doğrultusunda yapılacak işlemleri arka plan kodlarında işlemi gerçekleştirir ve Controller kavramı tam olarak işlemezdi. Ayrıca aspx ya da Asp sayfaların içerisine yönetilebilir kodların yazıldığı bir çok proje görebiliriz. Bu işlemin olması injection ataklarından tutunda yaptığımız projenin yavaş çalışmasına kadar bir çok olumsuz faktör ile bizi karşı karşıya bırakmaktadır. MVC Framework ile geliştirdiğimiz uygulamaların View sayfalarında ise sadece HTML kodların yazılmasına olanak tanınmaktadır. Sebebi ise performansın dışında gereksiz yere server 'a zorlayan işlemleri view sayfalarda kullanmamak. Çünkü bir işlem yapılmayacak dahi olsa view sayfaların açılmaktadır. Eğer ki kullanıcıların görecekleri sayfalara yönetilebilir kodlar eklersek sayfa açıldığında bu kodlarda işlenecek, sayfanın serverdan çağırılması esnasında yüklenmesi için geçecek zamanda da bandwith in dolmasına sebep olacaktır.

MVC uygulamalarında Controller katmanında olan sınıflarda oluşturulan metotlar ile eşleştirilmiş Viewlar üzerinde işlem yapılır. Controller üzerindeki metotlar 'da MVC 'ye göre Action işlemini gördüğünü daha önceki yazılarımızda incelemiştik. Kısacası MVC Framework 'te oluşturulan Viewler, Controller katmanında oluşturulan sınıflarda yer alan metotlar yani Action lara göre hazırlanır ve kod tarafında sadece html kodlar yer almaktadır.

MVC Framework ile varsayılan olarak oluşturulan HomeController.cs sınıfında Details() ve Index() metotlarını aşağıdaki gibi oluşturalım. Hatırlayacağınız üzere Controller da oluşturulan metotların isimleri Action olarak geçmektedir.

Controller\HomeController.cs
using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
             return View();
        }

        public ActionResult Details()
        {
             return RedirectToAction("Index");
        }
    }
}

İlk olarak inleyeceğimiz Action Index() olacak ve URL içerisinde nasıl gösterileceğine de göz atacağız.

/Home/Index

İkinci olarak Details() Actionına ve URL 'de nasıl gözükeceğine göz atalım.

/Home/Details

Oluşturulan metotlarda geri dönüş değeri view olmalıdır. ActionResult kullanımında geri dönüş değerlerinin neler olacağını daha önceki yazılarımızda incelemiştik. Index() metodu açıldığı sayfada isteğe cevap verilmesi için View() ı kullanmaktadır. Details() ise onu ilişkilendiren bir istek geldiğinde Index view ına yönlendirme işlemini yapmaktadır.

Index() actionının geri dönüş değeri olan View(); 'ı web sunucunu nasıl algıladığına göz atmak gerekirse,

/View/Home/Index.aspx

Yukarıda verdiğimiz yol web sunucuna giden adrestir. Peki bu bize ne anlama gelmektedir. En baştan itibaren View yapacağı ana işi belirtmektedir. Home eşleştirileceği Controller 'ın adını, Index Controller içerisindeki Action (Metot) adını belitmektedir.

Details() 'te olduğu gibi başka bir view 'a yönlendirmek istediğimizde elimizle ya da sistemden gelen bir parametre ile harici bir view adı veririz. Bunu web sunucumuzun nasıl anladığına göz atmak gerekirse,

View("sertur"); kullandığımızda /View/Home/sertur.aspx şeklinde olacaktır.

View a İçerik Eklemek

Şimdiye kadar View lar hangi amaçla oluşturulmakta ve Controller 'dan nasıl kullanıldığına değindik. Şimdi dinamik olarak HTML 'i nasıl kullanabileceğimize değinmeye çalışacağız.

Şimdi Index view 'ında şu anın zamanını HTML nasıl göstediğimizi bir hatırlayalım.

View\Home\Index.aspx
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>

<!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 id="Head1" runat="server">
       <title>Index</title>
   </head>
   <body>
      <div>
          <% Response.Write(DateTime.Now);%>
      </div>
   </body>
</html>

HTML sayfada günün zamanını sağlayan kod parçası <% Response.Write(DateTime.Now);%> dır. Tabii şimdiden dediklerinizi duyar gibiyim. "Eğer böyle kullanacaksak MVC kullanmanın anlamı ne? Azcıkta burada düzenleme yapsalardı" der gibisiniz. :) ASPX sayfalarımızın içerisine C# kod yazdığımızda da <% %> yazım şeklini kullanır ve içerisine scriptlerimizi C# olacak şekilde yazardık. MVC 'de ise HTML tarafına yönetilebilir kod yazılmasının yanlış olduğundan bahsetmiştik. Microsoft çalışanları da bu tür sık kullanımları görerek ufak kolaylıklar geliştirmişlerdir. Örneğin web sayfalarında bir değer göstermek için Response.Write() sık sık kullanmaktayız. Bu sebepten ötürü kullanmak istediğimiz sadece <%= %> kullanmamız yeterli olacaktır.

Örnek ile göstermek gerekirse,

View\Home\Index.aspx
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>

<!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 id="Head1" runat="server">
       <title>Index</title>
   </head>
   <body>
      <div>
          <%= DateTime.Now %>
      </div>
   </body>
</html>

İki işlem sonucunda da kullanıcının gördüğü aynı olacaktır. Ayrıca bize bir katkısı da html sayfada daha az metin kullanacağımız için sayfa boyutu daha da azalacak ve sayfanın bir öncekine oranla daha hızlı açılmasına olanak tanınmış olacaktır.

HTML Helper Kullanımı ile View İçeriğinin Oluşturulması

HTML Helper nesnelerini çağırarak View sayfamızında içeriğine çok hızlı ve kolayca oluşturabilmemiz mümkündür. HTML Helper metotları işlemleri sonucunda string tip üretmektedir. HTML Helper 'da standart HTML elementleri kullanılmaktadır. Bunları;

Html.ActionLink: <a> elementi oluşturarak bir action metoduna link verilmesini sağlar.
Html.BeginForm: <form> elementini oluşturur.
Html.CheckBox: Checkbox; yani <input type="checkbox"...> elementi oluşturur.
Html.DropDownList: <select..><option>..</option>.....</select> elementlerini(WebForm'lardan tanıdığımız DropDownList'in çıktısı) oluşturur.
Html.Hidden: HTML içerisinde gizli alan; yani <input type="hidden"...> elementi oluşturur.
Html.ListBox: <select multiple="multiple"..><option>..</option>.....</select> elementlerini(WebForm'lardan ListBox'ın çıktısını) oluşturur.
Html.Password: Şifre için metin kutusu oluşturur(<input type="password"...>)
Html.RadioButton: <input type="radio"....> elementi oluşturur.
Html.TextArea: Birden fazla satırı olan bir metin kutusu oluşturur(<textarea....> elementi).
Html.TextBox: Metin kutusu oluşturur(<input type="text"....> elementi).

olarak sıralayabilmemiz mümkündür.

Şimdi HTML helper kullanarak basit bir örnek oluşturalım. Örneğimizde BeginForm(), TextBox() ve Password() elementleri yer alsın.

View\Home\Index.aspx
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>

<!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 id="Head1" runat="server">
       <title>Login Form</title>
    </head>
    <body>
       <div>

          <% using (Html.BeginForm())
          { %>
  
             <label for="UserName">User Name:</label>
             <br />
                <%= Html.TextBox("UserName") %>

             <br /><br />
  
             <label for="Password">Password:</label>
             <br />
             <%= Html.Password("Password") %>
  
             <br /><br />
  
             <input type="submit" value="Log in" />
  
         <% } %>
 
      </div>
   </body>
</html>

Response.Write() yerine <%= %> kullanmamızın daha kolay olacağından bahsetmiştik. Bu sebeple TextBox() ve Password() kullanırken bu kullanım şeklini tercih ettik. Yaptığımız işlemler sonrasında karşımza çıkan görünüm aşağıdaki gibi olacaktır.

Gördüğünüz üzere sadece HTML helper ları kullanarak istediğimizi gerçekleştirdik. Peki, HTML kullanaraj bu işlemi yapmak isteseydik yazmamız gereken kod parçacığının nasıl olacağına değinelim.

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>

<!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 id="Head1" runat="server">
       <title>Login Form</title>
    </head>
    <body>
       <div>
       <form method="post" action="/Home/Login">

       <label for="userName">User Name:</label>
       <br />
       <input name="userName" />

       <br /><br />

       <label for="password">Password:</label>
       <br />
       <input name="password" type="password" />

       <br /><br />
       <input type="submit" value="Log In" />

       </form>
      </div>
   </body>
</html>

İki yöntemde de sorunsuz bir şekilde çözüm aldığımızı gördük. Ancak MVC kullanmak istediğimiz durumlarda HTML helper kullanmak çok daha yararlı olacaktır. Değindiğimiz ve bir süre daha değineceğimiz örnekler geliştirilen uygulamalar için çok basit kalabilir. Örneğin aklınıza GridView() kontrolü yok mu diye gelebilir. Verdiğimiz listeden de görebileceğiniz gibi yoktur. Ancak yazımızın devamında göreceğimiz üzere HTML Helper özellikleri kullanarak kendimiz GridView() 'ı oluturacağız.

View Sayfalara Verilerin Taşınması
Controller içerisnde View sayfalara veri aktarılması mümkündür. View Data özelliği ile bu işlemler gerçekleştirilebilir. Bu özellik gönderilen verilerin tamamını bir pakete alarak view sayfada kullanılabilir bir biçimde kullanılabilmesine olanak tanımaktadır.

ViewData özelliğini bir örnek ile incelemek gerekirse,

Controller/UrunController.cs
using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
    public class ProductController : Controller
    {
         public ActionResult Index()
         {
              ViewData["Mesaj"] = "Merhaba Dünya!";
              return View();
         }
    }
}

ViewData özelliğine view sayfada göstereceğimiz veriyi atıyoruz. Sonrasında Html.Encoding() özelliği ile gelen veriyi çözümleyerek son kullanıcı ekranında görünmesini sağlıyoruz. Html.Encoding() controller lardan gelen string verileri view sayfalarda görülecek şekilde çözümleyerek görüntülenmesine olanak tanımaktadır.

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Index
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <h2>Index</h2>
    <%= Html.Encode(ViewData["Mesaj"]) %>
</asp:Content>

Html.Encode() yardımıyla Merhaba Dünya! mesajımızı basitçe gösteriyor olduk. Bu işlemimiz sonucunda ekran görüntüsü aşağıdaki gibi olmaktadır.



Basit merhaba dünya örneğimiz dışında veri tabanında alınan verileri view sayfasında da göstermek istediğimiz ViewData ve Html.Encoding() kullanılması mümkündür.

Harici HTML Helper (Yardımcı HTML) Kullanımı
MVC uygulamalarında View sayfalarında gösterilen sayfa içeriğinin HTML Helper (yardımcı HTML) yardımıyla gösterildiğini görmüş ve geçmiş örneklerimizde bunları detaylı bir biçimde incelemiştik. Normalde alışık olduğumuz <form> elementinin yerine Html.BeginForm() özelliği kullanılmaktadır. HTML elementlerinin en sık kullanıldığı zamanlarda <input> ve <img> en çok tercih edilen elementlerdi. Zaman geçtikçe bunların yerini Asp.Net kontrolleri almıştır. Fakat Asp.Net kontrolleri de arka planda derlendiğinde <input> olduğu gözlenmiştir. Bu sebepten bizlere HTML Helper kütüphanesi hazırlanmış ve kullanımımıza sunulmuştur. Tekrardan kullanabileceğimiz en temel HTML Helper metotlarına göz atmak gerekirse;

•Html.ActionLink()
•Html.BeginForm()
•Html.CheckBox()
•Html.DropDownList()
•Html.EndForm()
•Html.Hidden()
•Html.ListBox()
•Html.Password()
•Html.RadioButton()
•Html.TextArea()
•Html.TextBox()
şeklinde sıralayabilmemiz mümkündür.

Not: View sayfalar kullanılan elementlerine HTML Helper 'ı çözümlerken <%= %> kullanımı ile <% %> birbirlerine eş değildirler. İkinci şekilde kullanmak istediğimizde uygulama hata verecek ve çalışmayacaktır.

HTML Helper ile Statik Metot Oluşturma

Basit olarak HTML Helper da kullanılmak üzere yeni bir statik metodu nasıl oluşturabileceğimize değineceğiz. Yapacağımız örnekte view sayfaya eklenecek kontrolde sabit değeri ve kullanıcının göreceği metin olacaktır.

Helpers\LabelHelper.cs
namespace MvcApplication1.Helpers
{
    public class LabelHelper
    {
        public static string Label(string target, string text)
        {
             return string.Format("<label for='{0}'>'{1}'</label>", target, text);
        }
    }
}

Geri dönüş değeri string olan statik bir metot hazırladık. Artık bizimde bir HTML Helper metodumuz vardır. Şimdi bunu View sayfada nasıl kullanacağımızı açıklamaya çalışalım. İlk olarak yapmamız gereken sayfaya Helpers alanını göstermemiz gerekmektedir. Bu işlemi <%@ imports %> ile yapacağız. Sonrasında ise <%= %> içerisine LabelHelper.Label  'ı kullanarak istediğimiz sonucu alabiliriz. Şimdi yazı olarak anlattıklarımızı uygulamalı olarak nasıl yapacağımıza değinmeye çalışalım.



<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Import Namespace="MvcApplication1.Helpers" %>
<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
   Home Page
</asp:Content>

   <asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
   <p>
   <div>
      <%using(Html.BeginForm())
      {%>

         <%=LabelHelper.Label("firstName", "First Name:") %>
         <br />
         <%=Html.TextBox("firstName")%>
         <br /><br />
         <label for="Password">Password</label>
         <br />
         <%=Html.Password("Password")%>
         <br /><br />

         <input type="submit" value="Giris" />

      <%}%>
   </div>
   </p>
</asp:Content>

View sayfamızda istediğimiz değerler sorunsuzca görülmektedir.



Artık kendimize ait bir HTML Helper sınıfımızı vardır. Fakat biz bu metotları kullanmak istediğimizde hangi sınıf adıydı diye hatırlamamız gerekecektir. En iyi yöntem Html Helper metotlarını extension lar yardımı ile kullanılmasına olanak tanımak olacaktır.

HTML Helper Uzantılı(Extension) Metotlar Oluşturmak

HTML Helper ile çalışırken MVC Framework bünyesinde oluşturulmuş olan metotları kullanarak view sayfalarımızın içeriklerini oluştururuz. Bu yöntem standart HTML elementlerinden yararlanılarak oluşturulmuş metotları projelerimizde Html Helper olarak kullanabilmemize olanak tanımaktadır. Şimdi biz örneğimizde HTML helper sınıfına ek bir metot ekleyerek html. koyduğumuzda bizim hazırladığımız metodunda kullanılmasını nasıl olacağını incelemeye çalışacağız.

Helpers\LabelExtensions.cs
using System;
using System.Web.Mvc;

namespace MvcApplication1.Helpers
{
    public static class LabelExtensions
    {
        public static string Label(this HtmlHelper helper, string target, string text)
        {
            return String.Format("<label for='{0}'>{1}</label>", target, text);
        }
    }
}

Visual Studio üzerinde intellisense i kullandığımızda view sayfada html helper için extension olduğuna bize belirtmektedir.



Yaptığımız değişikliğe göre index.aspx sayfamızı güncellersek sonuç aşağıdaki gibi olacaktır.
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Import Namespace="MvcApplication1.Helpers" %>
<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
   Home Page
</asp:Content>

   <asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
   <p>
   <div>
      <%using(Html.BeginForm())
      {%>

         <%=Html.Label("firstName", "First Name:") %>
         <br />
         <%=Html.TextBox("firstName")%>
         <br /><br />
         <label for="Password">Password</label>
         <br />
         <%=Html.Password("Password")%>
         <br /><br />

         <input type="submit" value="Giris" />

      <%}%>
   </div>
   </p>
</asp:Content>

Evet. Artık Html helper metotları gibi kullanılabilen bir metodumuz oluşmuştur.

Veri Tabanı Tablolarında Verilerin Gösterilmesi

Yazımızda şu ana kadar View üzerinde yapabileceğimiz temel işlemleri ve kendi istediğimiz doğrultuda HTML yardımcısı oluşturmayı incelemeye çalıştık. Yazımıza veri tabanı işlemleri sonucunda dönen verileri View sayfaları da html yardımcıları kullanılarak nasıl gösterebileceğimizi inceleyerek devam ediyoruz.

Konumuzu örnek üzerinde anlatmaya devam ediyoruz. İlk olarak yapılması gereken bir veri tabanı oluşturmak ve içerisine bir tablo eklemek olacaktır. Yazımızda kullanacağımız veri tabanının adı Sirket, Tablonun adı da Film olacaktır. Tablonun alanları ve tiplerine aşağıdaki resimden erişebilirsiniz.



Veri tabanı ve tabloyu oluşturduğumuza göre artık MVC Framework ile oluşturmuş olduğumuz projemize ekleyebiliriz. Bu işlemi yaparken Ado.Net Entity Framework 1.0 'ı kullanacağız. Projeye ekleyebilmek için Model klasörünün üzerine sağ tıklama yapıp çıkan ekranda Ado.Net Entity Data Model 'i seçerek ekle diyoruz. Sonrasında boş bir model oluşturacağız dedikten sonra veri tabanının ne olacağı gibi bilgileri girerek bir sonrasında modeli uygulamaya eklenmiş oluyor.


Artık film tablosu modele dönüştürüldü ve üzerinde işlem yapılmak üzere hazır durumdadır. Eğer model üzerinde bir işlem yapıyorsanız yapmanız gereken o dosyayı kaydetmek, sonrasında ise projeyi bir kere derlemek olacaktır. Sonrasında kullanılabilir sorunsuzca entity model kabiliyetlerini kullanarak işlemleri yapabiliriz.


Film Controller Oluşturuyoruz

Controller hakkındaki ayrıntılı bilgileri daha önceki yazılarımızda değinmiştik. Şimdi ise hızlıca controller 'ı oluşturup işlemlerimizi yapmaya devam edeceğiz. İlk olarak en başta projeye UrunController.cs sınıfını oluşturuyoruz.



Sonrasında karşımıza geçen ekranda Controller adını belirterek oluştur diyoruz.



Sınıfı oluşturduktan sonra düzenleme yapmaya başlıyoruz. Index() metoduna tablo içerisindeki verileri çekerek işlemi yapıyoruz.
using System.Linq;
using System.Web.Mvc;
using MvcApplication1.Models;
namespace MvcApplication1.Controllers
{
    public class FilmController : Controller
    {
        //
        // GET: /Film/

        public ActionResult Index()
        {
            var entity = new SirketDbEntities();
            return View(entity.FilmlerSet.ToList());
        }
    }
}

Veri tabanına eriştik ve sonuçlar artık view sayfada kullanılmak üzere hazır durumda bizi bekliyor. Şimdi view sayfayı oluşturarak işlemlerimize devam ediyoruz. Otomatik olarak oluşturulması için Index() metodunun üzerinde sağ tıklama yaparak AddView seçeneğini seçiyoruz. Sonrasında karşımıza gelen ekranı aşağıdaki şekline getirerek veri tabanından gelen verileri gösteren view sayfamızı oluşturmuş oluruz.



Otomatil olarak oluşturulan view sayfasındaki kodlar aşağıdaki gibi olmuştur.



<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<MvcApplication1.Models.Filmler>>" %>

   <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
      Index
   </asp:Content>

   <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

   <h2>Index</h2>

   <table>
      <tr>
         <th></th>
         <th>
            Id
         </th>
         <th>
            Film_Adi
         </th>
         <th>
            Yonetmen
         </th>
         <th>
            Cikis_Tarihi
         </th>
      </tr>

      <% foreach (var item in Model) { %>

      <tr>
         <td>
            <%= Html.ActionLink("Edit", "Edit", new { id=item.Id }) %> |
            <%= Html.ActionLink("Details", "Details", new { id=item.Id })%>
         </td>
         <td>
            <%= Html.Encode(item.Id) %>
         </td>
         <td>
            <%= Html.Encode(item.Film_Adi) %>
         </td>
         <td>
            <%= Html.Encode(item.Yonetmen) %>
         </td>
         <td>
            <%= Html.Encode(String.Format("{0:g}", item.Cikis_Tarihi)) %>
         </td>
      </tr>

      <% } %>

   </table>

   <p>
      <%= Html.ActionLink("Create New", "Create") %>
   </p>

</asp:Content>

Bu işlemler doğrultusunda ekran görüntüsü aşağıdaki biçimde olacak ve isteğimizi karşıladığını görüyor olacağız.



TagBuilder Sınıfını Kullanarak Html Helper Oluşturmak

TagBuilder sınıfını kullanarak resim ve benzeri dosyaları projede gösterebilmemiz mümkündür. Bu işlemleri gerçekleştirirken diğer view sayfalarda da kullanıldığı gibi html yardımcı (HTML Helper) yardımcı kullanılarak gerçekleştirilir.

TagBuilder sınıfınının genel yapısına göz atmak gerekirse,

AddCssClass() = Yeni bir css sınıfı eklenmesine olanak tanır. class=""
GenerateId() = Özniteliklerini ekleyerek id işlenir. Bu metot değişikliklerin periyodik olarak ID bazlı değişiklik olanağı tanır.
MergeAttirbute() = Özniteliklerini ekleyerek id işlenir. Aşırı yüklenmiş metotlar için kullanılmaktadır.
SetInnerText() = İç metin ayarlamak için kullanılır.
ToString() = Daha fazla etiket oluşturulmasına olanak tanımaktadır.

TagBuilder sınıfının dört önemli özellikleri vardır.

Attribute = Temsil edilen tüm etiketlerin özniteliklerini taşır.
IdAttributeDotReplacement = Tekrardan gösterilen etiketlerin GenerateId() metodu kullanılarak değişik periyotlarda işler.
InnerHTML = Temsil edilen etiketin iç içeriğini sunar.
TagName = Etiketi gösterir.

TagBuilder sınıfı

TagBuilder sınfı aslında gerçek bir kullanılan ana sınıf değildir. StringBuilder sınıfı miraslanarak oluşturulmuş bir sınıftır.


Resim Html Helper Oluşturuyoruz
TagBuilder sınıfının metotlarından GenerateId() ve MergeAttribute() metotlarını kullanarak controller ı oluşturulalım.

using System.Web.Mvc;
using System.Web.Routing;

namespace MvcApplication1.Helpers
{
   public static class ResimHelpers
   {
      public static string Resim(this HtmlHelper helper, string id, string url, string alternateText)
      {
         return Resim(helper, id, url, alternateText, null);
      }

      public static string Resim(this HtmlHelper helper, string id, string url, string alternateText, object htmlAttributes)
      {
         // Create tag builder
         var builder = new TagBuilder("img");

         // Create valid id
         builder.GenerateId(id);

         // Add attributes
         builder.MergeAttribute("src", url);
         builder.MergeAttribute("alt", alternateText);
         builder.MergeAttributes(new RouteValueDictionary(htmlAttributes));

         // Render tag
         return builder.ToString(TagRenderMode.SelfClosing);
      }

   }
}

TagBuilder sınıfını kullanarak kendi HTML Helper metodumuzu oluşturuyoruz ve view sayfada kullanılabilir duruma getiriyoruz. Bu noktada yapmamız gereken view sayfada Html.Resim() metodunu kullanmak olacaktır.
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Import Namespace="MvcApplication1.Helpers" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
   Index
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
   <h2>Index</h2>
   <%= Html.Encode(ViewData["Mesaj"]) %><br />
   <%= Html.Resim("img1", ResolveUrl("~/Content/editor_turhal.jpg"), "Turhal Temizer")%>
   <%= Html.Resim("img1", ResolveUrl("~/Content/editor_turhal.jpg"), "Turhal Temizer", new {border="4px"})%>
</asp:Content>

İşlemlerimiz sonucunda ekran görüntüsü aşağıdaki gibi olacaktır.



Yazımızda detaylı olarak view kavramına, Html Helper 'a ve kendi HTML helper metotlarımızı oluşturmayı detaylı bir biçimde incelemeye çalıştık. Bir sonraki Asp.Net MVC Framework yazımızda Model kavramını incelemeye çalışacağız.

Herkese mutlu günler diliyorum.