Showing posts with label MVC. Show all posts
Showing posts with label MVC. Show all posts

Sunday, May 01, 2011

Comparing the MVC and MVVM patterns along with their respective ViewModels

It won't take long in your quest to find more information on ASP.NET MVC through internet searches, with bing.com of course, before you'll stumble across the notion of a ViewModel. Mixed within those search results are links to articles on ViewModels in Silverlight/WPF, or other technologies that also use the MVC or MVVM patterns or ViewModels, which can be quite confusing. Having said that, it's no wonder in every presentation I give concerning MVC or ViewModels, a few folks frequently ask these two, quite reasonable, questions:

"What's the difference between MVC and MVVM ?" (in general)
"What's the difference between ViewModels in MVC and ViewModels in MVVM?"
The elevator pitch: MVC is a web UI pattern, and ASP.NET MVC is Microsoft's implementation of it. MVVM is Microsoft's implementation of a desktop UI pattern in WinForms, SilverLight or WPF.
MVC is an old pattern, in use for decades in non-Microsoft platforms, and MVVM is a pattern similar to Martin Fowler's Presentation Model (PM) pattern, as it has taken many of its concepts from PM.
It's all about the patterns
Both MVC and MVVM are patterns, meaning that they are solutions to recurring design problems in software development. Patterns can show interactions between objects in various ways, as the few listed below will demonstrate:

General interactions
Interaction through inheritance and OOP principles
UI interactions
Interaction between models, views, and controllers or models, views, and ViewModels
Data access patterns
ORM mappings, Active Record pattern, POCOs in DALS
Once you're aware of patterns, you can then apply them in software to make your code more stable, consistent, and maintainable. A variety of tools and frameworks exist that can easily help find the best pattern and/or implementation for your specific business problem/domain. In particular, the MVC and MVVM patterns are both UI interaction patterns with MVC being the web UI pattern and MVVM being a desktop UI pattern. You can implement either pattern in Visual Studio, and the ASP.NET MVC project template in particular guides developers to use the MVC pattern.
In addition to MVC & MVVM there are many patterns that are worth reading up on.
Comparing MVC and MVVM: the patterns.
Since MVC and MVVM are geared towards different application paradigms altogether, i.e., ASP.NET MVC for web and MVVM desktop, they need to behave in distinctly different ways, with the most noticeable distinction being the controller from MVC... 

Read more: Rachel Appel

Tuesday, April 26, 2011

Управление сессиями NHibernate в приложениях ASP.NET MVC

Здравствуйте, уважаемые читатели!
В этой статье я хочу ответить на типичный вопрос разработчика, начинающего использовать NHibernate в web-приложениях, разрабатываемых на основе ASP.NET MVC - как управлять сессиями и конфигурацией NHibernate в рамках веб-приложения. Это первая проблема, которая встречается разработчику, и для того, чтобы не потерять производительность, и не получить странных трудновоспроизводимых ошибок необходимо корретно реализовать этот механизм. В сети я находил несколько разных версий, и в этой статье я приведу ту, которая показалась мне наиболее удобной.

Итак, сначала немного теории. Как говорит вся документация на NHibernate - создавать конфигурацию и фабрику сессий затратная по времени операция, в то время как создавать сессию операция относительно быстрая. Таким образом, необходимо, чтобы в нашем приложении, конфигурация создавалась как можно реже, и была одна фабрика сессий, а сессии создавались для каждого HTTP запроса. Создавать больше одной сессии для HTTP запроса не имеет особого смысла.

Таким образом, самое подходящее место для конфигурирования и создания фабрики сессий - это обработчик Application_Start. Я использую DI-контейнер LinFu, но он может быть с легкостью заменен любым другим. Я думаю семантика выполняемых действий будет ясна из приведенного кода.

protected void Application_Start()
{
 AreaRegistration.RegisterAllAreas();
 var serviceContainer = new ServiceContainer();
 serviceContainer.AddService(CreateNhSessionFactory());
 ServiceContainerProvider.Init(serviceContainer);
 RegisterGlobalFilters(GlobalFilters.Filters);
 RegisterRoutes(RouteTable.Routes);
}
protected ISessionFactory CreateNhSessionFactory()
{
 var sessionFactory = Fluently.Configure()
  .Database(
   MsSqlConfiguration.MsSql2008.ConnectionString(
    x => x.FromConnectionStringWithKey("ApplicationServices"))
  )
  .Mappings(x => x.FluentMappings.AddFromAssemblyOf<Issue>())
  .BuildSessionFactory();
 return sessionFactory;
}

Думаю из кода видно, что в Application_Start конфигурируется NHibernate, создается фабрика сессий и помещается в DI контейнер. По умолчанию LinFu использует поведение типа Singleton (единственный объект на все приложение), если при регистрации сервиса передается конкретный объект. Итак, я добился того, что у меня будет одна фабрика сессий для всего ASP.NET MVC приложения. Замечу, что приложение ASP.NET - это отдельная тема для обсуждения, но как минимум следует знать, что в одном приложении могут обрабатываться тысячи запросов, создает и уничтожает приложение IIS в соответствии с настройками. Теперь нужно сделать так, чтобы у нас на один запрос была только одна сессия, которая будет использоваться всеми классами слоя доступа к данным.

Read more: Brain IT!

Friday, April 08, 2011

Организуем view models в ASP.NET MVC

В интернете полно примеров вроде «Делаем вики на ASP.NET MVC за 15 минут». Проблема таких примеров в том, что они используют VideData или ViewBag для передачи данных в View. Для генерации форм используются нетипизированные методы вроде Html.TextBox(). А для получения данных из форм просто параметры к методам контроллера, или хуже того – сами сущности из ORM.

Это может быть прекрасно с точки зрения того, кто в жизни имеет дело только с созданием таких «видео уроков». Но в немного более сложных случаях вы, конечно же, захотите иметь строго типизированные модели, использовать строго типизированные методы вроде Html.TextBoxFor(m=>..), и получать в методе контроллера из формы ровно то, что хотите получить и при этом держать все модели в консистентном виде.

Итак, правила, если вы хотите разрабатывать в MVC:
Каждому View свой персональный класс ViewModel.
Только View диктует, какие будут свойства у ViewModel. Остальное – проблемы контроллера.
ViewModel – это простой DTO, без логики.
View использует только те данные, которые приходят из ViewModel, ничего больше. Не трогайте Request.IsAuthenticated в ваших View, для этого есть модель.
Может возникнуть вопрос, а как быть с _Layout (мастер страницами) – ведь это тоже View и они тоже хотят свои модели. Вполне резонно – ведь мы помним, что view диктует модель, всё остальное следует потом. Поэтому создайте в приложении класс SharedLayoutViewModel с нужными вашему _Layout.cshtml свойствами, и наследуйте от него ваши модели для остальных View. Пользуйтесь Result-фильтрами чтобы наполнять эту модель в одном месте для всех методов ваших контроллеров. Или переопределите OnResultExecuting в базовом классе ваших контроллеров, и делайте это там.

Read more: Habrahabr.ru

ASP.NET MVC 3.0 Internals

ASP.NET MVC 3.0 Internals
בפוסט זה אני רוצה לכתוב על איך עובד ה- ASP.NET MVC 3.0 ואיפה אפשר להרחיב ולשנות את הטכנולוגיה.
אני מחלק את הפוסט לארבעה חלקים:
1. החיבור בין ASP.NET ל- ASP.NET MVC
2. Controller Extensibility
3. Model Extensibility
4. View Extensibility
1. החיבור בין ASP.NET ל- ASP.NET MVC.
ה- MVC חי בתוך ה- ASP.NET וכדי לשנות את סדר הפעולות שקורות ב- ASP.NET הוא משתמש במנגנון ה-
Routing שנוסף בדוט-נט 4, הוא רושם אוביקט Route ל- RouteTable.


clip_image002_thumb_7B0D9450.png

ב- Global.asax.cs אנחנו יכולים לראות את הקוד הבא:

routes.MapRoute(
    "Default",                    // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new                           // Parameter defaults
    {
       controller = "Home",
       action     = "Index",
       id         = UrlParameter.Optional
    }
);
המתודה MapRoute היא Extension Method תפקידה ליצור אוביקט Route שמקשר בין ה- "{controller}/{action}/{id}" ל- MvcRouteHandler. אם מסתכלים בתוך הקוד של המתודה MapRoute נמצא את השורות הבאות:
var route = 
     new Route( url , new MvcRouteHandler() )
     {
        Defaults    = new RouteValueDictionary(defaults),
        Constraints = new RouteValueDictionary(constraints),
        DataTokens  = new RouteValueDictionary()
     };

Read more: I Love C#

Tuesday, March 08, 2011

Using a custom build of MVC 3

Disclaimer: running a custom build of MVC 3 is not recommended in most scenarios. Please run against the official MVC 3 bits unless you really cannot. Be aware that using custom builds will make it harder to use 3rd party libraries built against the official bits (you’ll need to rebuild those libraries).
One nice thing about ASP.NET MVC is that you can get the full sources on CodePlex and compile them yourself.

Once you copy the sources locally, you can open the WebRuntime solution in VS 2010 and build it. As an aside, note that this solution also contains the ASP.NET WebPages sources, since MVC3 makes you of some of that logic (mostly for Razor support).
So this lets you modify the sources and build everything. However, one thing that makes the use of the resulting assemblies a bit tricky is that unlike the official bits, the bits produced by this solution are unsigned.

Let’s take this step by step.

Step 1: Create a new MVC 3 application
So let’s start by creating a new MVC 3 Web Application using the regular project template that come from installing MVC 3.
This gives you a working app, but obviously at this point your still using the official MVC 3 bits.

Step 2: Reference your custom assemblies
The next step is to reference your custom MVC assemblies. Start by removing the System.Web.Mvc and System.Web.WebPages references. Instead, reference the version you’ve built of those same assemblies, which you’ll find under mvc3\bin\Debug (from the root of the WebRuntime solution).

Once you do that, your MVC project will build fine. However, if you try running it, you’ll get some scary looking runtime compilation error. Something like:
CS0433: The type 'System.Web.Mvc.WebViewPage<TModel>' exists in both 'c:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Web.Mvc\v4.0_3.0.0.0__31bf3856ad364e35\System.Web.Mvc.dll' and 'c:\Users\David\AppData\Local\Temp\Temporary ASP.NET Files\root\d305385c\948d4291\assembly\dl3\ef116fd6\5f110ce1_44dccb01\System.Web.Mvc.DLL'

The reason this happens is that while you’ve changed the project references to point to your assembly, the two web.config files that come with the project template are still pointing to the official assemblies left and right. Which leads us to…

Step 3: Fix up your web.config files
The project comes with two web.config files, and they each contain all kind of references to the official assemblies (which are strong name). e.g. in the root web.config, you’ll find:

Read more: David Ebbo

Friday, March 04, 2011

XAMLtoMVC dynamic image generator

What XAMLtoMVC is for
XAMLtoMVC was created to ease tasks in web development when you have something to display that is impossible (or nearly impossible) with html. And especially with images you want to use, but you realize you can't because they are too static to reflect even the smallest changes.
The solution is based on MVC actions and Html helper methods creating images ondemand.
Let’s see some example problems and the extension methods that cure the pain.


Problems that can be solved with XAMLtoMVC
Problem 1. Your web page is designed with glossy buttons that have custom typefaces.

FileDownload.aspx?ProjectName=xamltomvc&DownloadId=211041

Problem 2. You'd like to display user-uploaded images on your webpage in a polaroid-like frame with a soft shadow and a watermark on it.

FileDownload.aspx?ProjectName=xamltomvc&DownloadId=211042

Read more: Codeplex

Getting ASP.NET MVC application to work on IIS 6.0

איך להתקין אפליקציית Asp.net MVC על שרת iis 6.0.
שלב 1: התקנת Asp.net Mvc
מכאן אפשר להוריד את ההתקנה ל – Asp.net MVC 2. יש להוריד את הקובץ AspNetMVC2_VS2008.exe
לאחר ההורדה יש לחלץ את ההתקנה.
פתח Cmd, גש לתיקיה שבה נמצאת ההורדה וכתוב את הפקודה הבאה:
AspNetMVC2_VS2008 /x   
נפתח חלון להכנסת שם התיקייה, ולאחר הזנת השם נוצרת תיקייה חדשה בשם שנתת, מתוך התיקייה שנוצרה תחת המחיצה של mvcruntime יש את הקובץ aspnetmvc2.msi אותו יש להתקין על השרת.
clip_image002_thumb_2B5750DD.jpg
שלב 2: wildcard
כדי שאפליקציית mvc תעבוד צריך להגדיר על ה – VirtualDirectory מיפוי כך שהלינקים באפליקציה שאין להם סיומת aspx  יעבדו.
תחת ה – properties ב – VirtualDirectory יש לבדוק שהגירסה של asp.net היא 4.0.
image_thumb_6790FD5D.png

Read more: Dovi Perla's Blog

Tuesday, March 01, 2011

ASP.NET MVC ‘Extendable-hooks’ – ControllerActionInvoker class

There’s a class ControllerActionInvoker in ASP.NET MVC. This can be used as one of an hook-points to allow customization of your application. Watching Brad Wilsons’ Advanced MP3 from MVC Conf inspired me to write about this class.

What MSDN says:

“Represents a class that is responsible for invoking the action methods of a controller.”
Well if MSDN says it, I think I can instill a fair amount of confidence into what the class does. But just to get to the details, I also looked into the source code for MVC.

Seems like the base class Controller is where an IActionInvoker is initialized:

protected virtual IActionInvoker CreateActionInvoker() {

return new ControllerActionInvoker();
}

In the ControllerActionInvoker (the O-O-B behavior), there are different ‘versions’ of InvokeActionMethod() method that actually call the action method in question and return an instance of type ActionResult.

protected virtual ActionResult InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters) {

object returnValue = actionDescriptor.Execute(controllerContext, parameters);
ActionResult result = CreateActionResult(controllerContext, actionDescriptor, returnValue);
return result;
}

I guess that’s enough on the ‘behind-the-screens’ of this class. Let’s see how we can use this class to hook-up extensions.

Say I have a requirement that the user should be able to get different renderings of the same output, like html, xml, json, csv and so on. The user will type-in the output format in the url and should the get result accordingly. For example:

http://site.com/RenderAs/ – renders the default way (the razor view)
http://site.com/RenderAs/xml
http://site.com/RenderAs/csv

… and so on where RenderAs is my controller.

Read more: IBloggable - implemented

Monday, February 28, 2011

New release of Mvc Controls Toolkit on Codeplex

Hi, for thes one using my Mvc Controls Toolkit library. The new version targetted also for MVC 3 is ready and available for download on Codeplex. Now the Mvc Controls toolkit is a complete set of server Controls (or helpers..). Have fun...

I apologize for some bug that you might find using it :)
I would like to thank the whole Microsoft Mvc Team for the great job done in connecting Asp.net Mvc with both JQuery Ajax and jQuery Validation in a server side transparent way. Not only a good job, it is Art!

Read more:  ASP .NET Forum
Read more: Codeplex

Sunday, February 27, 2011

ASP.NET MVC Data Access Videos & Tutorials (17)

ASP.NET MVC App Building Videos (61)

Sunday, February 20, 2011

Обновляем приложение с MVC 2 до MVC 3

Уже год мой сайт (блог) живет на самописном движке, который я сделал при помощи ASP.NET MVC 2. Конечно же я мог пользоваться бесплатными площадками для блогов, но мне пока интересно развиваться по многим направлениям. И если моя основная специальность сейчас Silverlight/WPF, то я все равно стараюсь не забыть про старый добрый веб, без него никуда в нынешнее время. Ну и нужно быть на гребне волны, потому я и решил что пора бы проапгрейдить свой сайт с MVC2 до MVC3. Зачем? А просто, чтобы было. Чтобы в будущем, когда захочется что-то допилить или доделать, а у меня уже была последняя версия, и я мог использовать последние фичи технологии.

Обновляем проект с MVC2 до MVC3

Первое задание, которое нужно выполнить для обновления на новую версию – это обновить сам проект и библиотеки. Если еще сама платформа не скачена, тогда идем на официальный сайт ASP.NET MVC и качаем третью версию отсюда http://www.asp.net/mvc/mvc3. Дальше нам нужно просто поменять references с библиотек версии 2.0 на версию 3.0. Делается это очень просто, качаем ASP.NET MVC 3 Application Upgrader (все бы производители фреймворков так заботились о разработчиках), запускаем, указываем путь до sln файла проекта и ждем результата. Эта тулза так же положит последние версии файлов jQuery фреймворка вам на сайт, но так как я использую Google jQuery CDN (чего и вам советую), то я просто вынес эти файлы из своего проекта и просто поменял ссылку на версию jQuery файла с 1.4.2 на 1.4.4. Еще эта библиотека заменила references во всех моих проектах этого солюшена с MVC 2.0 на MVC 3.0 (и добавила ссылки на две дополнительные библиотеки), как и должна была, а так же обновила web.config файл, а именно добавила в appSettings пару параметров, предназначения которых я пока не знаю:

<add key="ClientValidationEnabled" value="false" />
<add key="UnobtrusiveJavaScriptEnabled" value="false" />
Потом разберемся, что это значит.

Read more: outcoldman

Monday, February 14, 2011

MotherEffin HTML5 Boilerplate MVC 3 Site Template

This past week I’ve been reading up on the HTML5 Boilerplate project by Paul Irish (of the Google Chrome and jQuery teams fame).  The HTML5 Boilerplate project is a collection of all the best practices for modern day web development in one easy to use project template.

Read more: Clarity consulting

Tuesday, February 08, 2011

ASP.NET MVC Performance Tips

Database access is usually the largest performance bottleneck of web applications. But once you’ve optimized and cached your database queries as much as possible here are 3 quick tips that might help you squeeze out a few more requests out of your ASP.NET MVC applications and web servers.
Depending on which features you are using they might not always apply to your application and their benefit will not be that significant (a few % points improvement at most – sorry I don’t have more specific numbers as I’m writing this from memory). I can’t guarantee how much improvement you will see as it depends so much on what your application does. But I hope this will provide some leads for you to investigate. Just remember to always measure for your specific scenario.

Disable unused view engines

When: Your application is using built-in display/editor templates (via the Html.EditorFor or Html.DisplayFor methods) and you are using only one type of view engine.
Why: ASP.NET MVC is generally very good about caching file lookup hits (views, partials, display/editor templates). However one scenario that is not cached is the use of the built-in (default) display/editor templates (where all file lookups are misses).
Any time you use the Html.EditorFor or Html.DisplayFor methods and you do not have a matching template file MVC will generate the appropriate markup for you based on the model’s metadata. However, before that happens it checks all the view engines to find a template file. The more view engines you have registered the longer this will take and since the miss is not cached the process will have to be repeated the next time a page is requested. If you are using only one view engine in your project you should remove the other ones in Global.asax.

Read more: MSDN Blogs

Monday, February 07, 2011

Быстрое создание прототипа веб приложения в ASP.NET MVC 3 с использованием MvcScaffolding

В этой статье я бы хотел рассмотреть возможность быстрого создания функционального прототипа веб приложения на основе технологии ASP.NET MVC 3. Немного соприкоснувшись с «Ruby on Rails», я заинтересовался его возможностью Scaffolding-га т.е. быстрого способа генерации основного каркаса приложения. Это дает возможность разработчику сконцентрироваться на создании бизнес модели и получить функциональный прототип не тратя свое время на детали реализации, что очень важно в начале любого проекта. А существует что-либо подобное в ASP.NET MVC? И насколько это функционально, быстро, удобно и практично.

Я хотел бы рассмотреть это на конкретном примере, и в этом качестве предлагаю создать простой веб каталог товаров. В моем случае это будет каталог автозапчастей.
В качестве инструментов, я буду использовать следующие средства разработки и библиотеки.
  • MS Visual Studio 2010
  • ASP.NET MVC 3 – официальный релиз
  • NuGet – менеджер пакетов для Visual Studio
  • MvcScaffolding — генератор кода MVC на основе шаблонов
  • EFCodeFirst — новая возможность Entity Framework CPT5
Установка и настройка

Прежде всего, необходимо настроить наше окружение. Найдите в менеджере расширений Visual Studio расширение NuGet и установите его. Либо скачайте и установите с официального сайта.

Создайте новый ASP.NET MVC 3 проект.

Далее нужно с помощью командной стоки менеджера пакетов установить MvcScaffolding. Откройте консоль NuGet: Главное меню «View” → „Other Windows“ → „Package Manager Console“.

Как мы увидим позже, эта командная строка является основным средством работы с MvcScaffolding, и аналогична командной стоке в Rails.
Для установки пакета достаточно выполнить команду:

Install-Package MvcScaffolding

Read more:  Habrahabr.ru

Sunday, February 06, 2011

איך מממשים MVVM ? זה הרבה יותר פשוט ממה שחושבים.

לממש MVVM הרבה יותר קל ממה שנשמע. משום מה יצא לDesign Pattern הזה שם של Design Pattern מורכב, ולפי דעתי זו סתם חוסר הבנה. הDesign Pattern במהותו פשוט עד טריוויאלי.
בפוסט הקודם דיברתי על הסיבות לממש MVVM, ועל הפואנטה שעומדת מאחורי הDesignPattern הזה. העליתי גם שאלה – מה גורם להפרדה של XAML ו Code Behind לא להוות הפרדה מספיק טובה.
אז האמת שההפרדה של XAML ו CodeBehind כבר לא ממש רעה, רק שהבעיה היא שהם לא ממש מופרדים – הם למעשה מהווים ביחד מחלקה אחת, ולכן שינויים באחד מהם לעיתים מאוד קרובות "ישברו" את השני. (ה Coupling כאן גבוה, ואת זה נרצה לשנות).
כל הרעיון מאחורי MVVM זה פשוט לקחת את הCodeBehind ולהוציא אותו למחלקה נוספת, שנקרא לה ViewModel, וכן תהייה לנו הפרדה חזקה.ה View יהיה הXAML, והלוגיקה תשב במחלקה נפרדת לחלוטין.
בנוסף, נקבע שאסור לView להכיר את הViewModel, ואסור לViewModel להכיר את הView. זאת אומרת שלא תהייה לנו אף פעם גישה מאחד לשני בצורה ישירה, וכך ההפרדה תשאר חזקה – כך שינויים בשכבה אחת לא ישברו את השכבה השניה אף פעם!
הבעיה היחידה היא כמובן איך מתבצעת שליטה של שכבת הלוגיקה (ה ViewModel) על שכבת התצוגה (ה View) אם הן שתי מחלקות נפרדות, ש"לא מכירות" אחת את השניה? כאן נכנסים שני פיצ'רים מאוד חזקים של WPF ו Silverlight – Binding – שעביר מידע בין הViewModel לבין הView, ו Commands, שיעבירו פקודות מהView לViewModel. זה הרבה יותר פשוט ממה שזה נשמע.
בשביל שהמחלקות יכירו אחת את השניה בצורה "חלשה", נקבע את מחלקת הViewModel להיות הDataContext של מחלקת הView. התקשורת בין שתי המחלקות תעבור לפיכך, ע"י שימוש בBinding וCommands.
אז תכלס, איך מממשים את זה?
כדוגמא ניקח את המסך הבא, שמראה כפתור ו ListBox. בלחיצה על הכפתור, ה ListBox יראה לנו רשימה של מוצרים:

Read more: Lego for grownups

Sunday, January 30, 2011

Unit Testing ASP.NET MVC Routes

Two things I always encourage customers to do are;
  1. Always delete the default route pattern after a File –> New project. This helps you focus on designing your routes throughout your site, and helps reduce SEO-unfriendly routes etc.
  2. Always unit test your routing table.
For number two, this is because it is so easy to have a route that looks like this;
/products/{productname}/{action}

… and then a developer comes along and adds a new route higher up the routing table that looks like this;

/products/{category}/{subcategory}

Hey presto, your website is broken. No-one can navigate to the {productname} pattern (assuming you have no other route validation going on). For this reason it is essential to unit test your routing table for any website, especially if it’s already live and you’re modifying it and adding functionality over time, because you could easily take down a whole piece of functionality. Remember to apply all the routes from every Area in your application during testing.

Read more: Simon Ince's Blog

ASP.Net MVC - Multi Form and Multi Submit Button Handling

Introduction
This article is inspired by the blog that showed excelled approach for using ActionNameSelector attribute. I have tried to take this approach little further to support multiple forms and multiple submit buttons without providing any hardcoded value to the attribute but just by specifying name of the form and button this action intended to handle. This makes sense when you don’t want to specify any Value directly inside code, as in case of localization when Value of buttons is not fixed.
Let’s design our approach for both the scenarios.

1. Multiple forms on same page

We will have an attribute to handle this scenario that will look for the form name from which the request has been posted. To have this we need to store form name in hidden field. So let’s create extension method of BeginForm to handle this.

public static MvcForm BeginForm(this HtmlHelper htmlHelper, string formName)
{
   return BeginForm(htmlHelper, null, formName);
}

public static MvcForm BeginForm(this HtmlHelper htmlHelper, MvcForm form, string formName)
{
   if(String.IsNullOrEmpty(formName))
       throw new ArgumentNullException("formName");
   if (form == null)
       form = htmlHelper.BeginForm();
   htmlHelper.ViewContext.Writer.WriteLine(htmlHelper.Hidden("n.__formName", formName));
   return form;
}

Now we have our hidden field rendered along with form name in output inside the current form tag. Below is the output of the page for View page

@using (Html.BeginForm("LogOn"))
{  }
@using (Html.BeginForm("ChangePassword"))
{  }

View Output

<form action="/" method="post"><input name="n.__formName" type="hidden" value="LogOn" />
</form>
<form action="/" method="post"><input name="n.__formName" type="hidden" value="ChangePassword" />
</form>

Now let’s design ActionNameSelectorAttribute

[AttributeUsage(AttributeTargets.Method)]
public class FormActionSelectorAttribute : ActionNameSelectorAttribute
{
   private readonly string[] _formName;
   public FormActionSelectorAttribute(params string[] formName)
   {
       if (formName == null)
           throw new ArgumentNullException("formName");
       _formName = formName;
   }
   public string[] FormName
   { get { return _formName; }
   }
   public override bool IsValidName(ControllerContext controllerContext, string actionName, System.Reflection.MethodInfo methodInfo)
   {
       return _formName.Contains(controllerContext.RequestContext.HttpContext.Request.Form["n.__formName"]);
   }
}

Implementation

[HttpPost]
[FormActionSelector("LogOn")]
public ActionResult Index(LogOnModel logOn)
{
   var account = new Account {LogOn = logOn};
   return View(account);
}
[HttpPost]
[FormActionSelector("ChangePassword")]
public ActionResult Index(ChangePasswordModel changePasswordModel)
{
   var account = new Account {ChangePassword = changePasswordModel};
   return View(account);
}


2. Multiple submit buttons inside same form

As we don’t want to do check using value of button we need to follow same approach that we used in form names. But in this scenario our value of hidden filed should be decided on click of that button. So now we will have to handle this from client side. Rather than adding this hidden field right from we will use small script to create only when needed. You can do this just like we did in multi form scenario, but I prefer it this way. Here I’m going to add new attribute to submit button to attach our function on click of it.

Read more: Codeproject