Scott Cate's WebLog

You just don't know what
you don't know.

community

frenz

my book(s)

my products

Very Quick MVP Pattern to Use with ASP.NET

The MVP is used for a lot of reasons, but mainly it does a **VERY** nice job of separating business logic from the UI.

M. = Model

V. = View

P. = Presenter

UX. = User Experience ( Web Form in this case)

In this implementation of MVP, Model will not be used. Only V and P with UX. The Model is where your data activity, and other "stuff" goes. This example is just meant to show how to get business logic out of your UX code.

Here is a basic Contact Us Web Form that we'll build with the MVP Pattern.

The first step of MVP is to create a contract. We're going to use a .Net Interface for that. Create a file called IContactUs.cs and use this code. This is our VIEW in the MVP.

public interface IReaderContactUs
{
    string Name { get; }
    string Email { get; }
    string PhoneNumber { get; }
    string Message { get; }
    string Result { set; }
}

The interface is like a blue print to a house. No implementation, just directions. This interface says that we have to be able to "GET" Name, Email, PhoneNumber, and Message. And that we have to be able to "SET" a Result string.

Next we need a Presenter. The presenter is the worker bee. The presenter actually does the work. Interestingly, the Presenter knows **NOTHING** about the UX. Repeat **NOTHING**. The presenter is usually in a different class library, and only referenced from the UX code. In order to enforce out contract (the .net interface we just created) we want to only be able to create a presenter, with an instance of the Interface. To do this, notice that our only constructor takes a single param that is the interface. Here is the code for our presenter; named ContactUsPresenter.cs

public class ContactUsPresenter
{
    private readonly IReaderContactUs view;

    public ContactUsPresenter(IReaderContactUs view)
    {
        this.view = view;
    }

    public void ProcessForm()
    {
        //do something - save it, send it, process it
        //in this case, just modify the UI, so we
//know it's running.
//This is where you would normally make a call into the model
        StringBuilder sb = new StringBuilder();
        sb.Append(string.Format("Name : {0}<br />", view.Name));
        sb.Append(string.Format("Email : {0}<br />", view.Email));
        sb.Append(string.Format("Phone : {0}<br />", view.PhoneNumber));
        sb.Append(string.Format("Message : {0}<br />", view.Message));
        view.Result = string.Format("<h1>Success</h1>{0}<hr />", sb);
    }
}

Finally we get to the code behind of our Web Form. Our web form Implements the Interface. All this means is that our web form has to be able to "GET" Name, Email, PhoneNumber, and Message. And that we have to be able to "SET" a Result string. Notice the appropriate Get / Set routines that wrap around the asp.net server controls.

Notice that we have a private ContactUsPresenter, that doesn't get instantiated until the OnInit event. This is because we have to send in an instance of the interface, which is the this keyword. Then when the button is clicked, the presenter.ProcessForm(); is called to do the work.

public partial class ContactUs : UserControl, IReaderContactUs
{
    private ContactUsPresenter presenter;

    public string Name { get { return NameTextBox.Text; } }
    public string Email { get { return EmailTextBox.Text; } } 
    public string PhoneNumber { get { return PhoneTextBox.Text; } }
    public string Message { get { return MessageTextBox.Text; } }
    public string Result { set { ResultLabel.Text = value; } }
    
    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        presenter = new ContactUsPresenter(this);
    }

    protected void Page_Load(object sender, EventArgs e)
    {
    }

    protected void SubmitContactButton_Click(object sender, EventArgs e)
    {
        presenter.ProcessForm();
    }
}

I hope this is helpful, and is a good starting point for the pattern.

Comments

Pete said:

Interesting. Where would validation take place in this configuration?

Cheers, Pete

# April 12, 2007 9:45 PM

Joe Chung said:

This isn't a good MVP pattern.

Using a Label control to render HTML is like using an object variable to store all your variables.  It's wrong.  Don't do it.

I'm actually working on an ASP.NET project where the original developer uses HTML string builders and Label controls render all his HTML.

Let's not try to wedge MVP into frameworks like ASP.NET that don't support it well.  Rather, let's change ASP.NET to support MVP better.

# April 13, 2007 5:56 AM

Dan said:

A brief description of the Model section would also be interesting.

Thanks, Dan

# April 13, 2007 9:02 AM

Chris said:

This is a good example and easy to understand since I'm just beginning to learn the MVP pattern. I was wondering if you could show an example with the Model so I can complete the picture.

# April 13, 2007 9:51 AM

Kevin Jensen said:

can you also recommend a namespace naming convention for MVP model?

# April 13, 2007 10:07 AM

scott cate said:

Joe Chung,

I'm not sure I follow. The label control is a simple control in asp.net. The only thing i don't like about this example, is that I stuffed HTML back into the result. In a win forms app, that wouldn't work.

But that's not the point here. the point is to show how to separate the code nicely.

Just because someone misused a control once, doesn't make it a bad control.

The beauty is that since I don't have code behind dictating my UX, i could easily change it to a placeholder, another customer server control, or anything, **WITHOUT** changing my biz logic.

# April 13, 2007 11:29 AM

scott cate said:

Pete,

Validation is a very interesting question. I get asked this a lot. My first answer is alway, X types of validation, not one, so validation can, and should, live in multiple places.

Here's an example.

The UX as the user to supply a date. I believe that the UX should have some UX validation, to ensure that the date is in-fact valid. Web does this diff than Win, which does it diff than smart client(phone), which again would be different on a cash register. So I think validation of user input should be in the UX. It's UX code. It directly effects the UX and nothing but the UX.

Then I think there should be business validation. Birthday for example, for your current customers, should not be more that 1XX years old. You decide the number, i don't care. This is a business decision on a date, that should be validated in the business code.

Validation Duplication? (nice rhyming)

Some validation will no doubt be duplicated. I'm OK with that - better safe than sorry.

I look at is like this. They're two diff systems. I'm in charge of the Business, and You're in charge of the UX.

It's up to you to create a pretty/nice/working/easy to use UX. If you don't validate the date, I will, and I'll throw and exception for you to catch. (hopefully you'll catch it right?)

Central Validation.

I'm not saying that I'd put validation all over the client code either.

I'd probably create a central routine for the interface like...

public bool ContactUsValidator(IReaderContactUs instance) {

 bool result;

 /// do some checking on "instance"

 return result.

}

Hope that helps.

-=- Scott

# April 13, 2007 11:38 AM

Palermo4 said:

I for one appreciate you taking the time out of your schedule to write this blog.  You never claimed to offer a "purist" version of MVP.  What you *did* accomplish is giving other ASP.NET developers an opportunity to think outside of the box... do something different.

If possible, I would like to see a follow-up blog (part 2) to demonstrate the whole point.  Perhaps show screenshots of different UX implementations?

# April 13, 2007 11:47 AM

Brian Leahy said:

To expand on scott's example, if you needed to validate the user's input before kicking off process, you would want to modify the Interface like so.

public interface IReaderContactUs

{

   string Name { get; }

   string NameIsValid{set;}

   string Email { get; }

   string EmailIsValid{set;}

   string PhoneNumber { get; }

   string PhoneNumberIsValid { set; }

   string Message { get; }

   string MessageIsValid { set; }

   string Result { set; }

}

This will allow the UI to render whatever it needs when something is invalid.  Though to seperate concerns you may want to make an IValidateContactUs and leave the original IReaderContactUs alone.

# April 13, 2007 12:48 PM

scott cate said:

Brian Leahy,

This is a solution, but you're relying on the client (the UX) to do validation. Depending on the scenario, this may be OK. If you trust the client developer.

And if that's good, I REALLY recommend separating the interfaces. IValidateContactUs.

# April 13, 2007 12:57 PM

Brian Leahy said:

Opps i biffed that one, no wonder the confusion.  I meant to make interfaces like so:

public interface IRequireContactUsValidation

{

  string Name { get; }

  string NameIsValid{set;}

  string Email { get; }

  string EmailIsValid{set;}

  string PhoneNumber { get; }

  string PhoneNumberIsValid { set; }

  string Message { get; }

  string MessageIsValid { set; }

  string Result { set; }

}

Where an IValidateContactUs has the method

public void ValidateContactUs();

taking IRequireContactUsValidation in it's constructor.

If the Interface is seperated to an IValidateContactUs that would allow one developer to write the validation logic which is testable, and the UI developer to center on The Validation error display.

So lets say company x has different validation rules from company y.  When writing validation rules you would have two concrete implementors of the IValidateContactUs.  The UI developer would select which validator to use and which presentor to use, not concerning himself with that logic.

If Customer x wants red circles to display when a field is invalid, then when implementing NameIsValid in the IRequireContactUsValidation(long name i know), he/she would put something like:

NameIsValid { set{ _nameIsInvalidErrorNotice.Visable = value;}}

Where _nameIsInvalidErrorNotice is a control that displays a flashing red circle next to your _txtName textbox.

When customer z looks at the demo application and says, I want that to error to be a popup box, You create  new implimentor of IRequireContactUsValidation changing only the implimentation of the IsValid properties.  If the rules for validation changes then you make a new IValidateContactUs implementor.

# April 13, 2007 7:44 PM

Brian Leahy said:

Ug i totally biffed what i ment to say.  IValidateContactUs was ment to look like:

IValidateContactUs

{

void ValidateContactUs();

}

Implementors would need to take a IReaderContactUs in the constructor.

That way the Implementor of IReaderContactUs would worry about Displaying the errors and not validating the error.  Opps.

# April 13, 2007 8:43 PM

jc said:

Hmmm... this is a tough one to recommend. Involved in a project using a very similar type of presenter pattern and it has convoluted the code immensely.

# April 17, 2007 9:46 PM

scott cate said:

jc, I've been using this pattern, and variations on it for years. And i don't thin there is any convolution going on. Especially when you use the same presenter in more than one place. Then it really pays off.

# April 18, 2007 5:21 PM

Amit Bhatia said:

Yes this is a very good example of learning MVP Pattern. The thing which remains in this is Model and Provider Part.

Model basically concentrate data only.And again which is going to be filled by presenter. Model is present inside the View.

Provider is the one which is used to get Data from the Web Services in Asp.Net and fills the Model and give that to Presenter and then presenter provide back that to UI.

# July 19, 2007 1:12 AM

Scott Cate's WebLog said:

With the help of the INETA.org speakers bureau, I've made my way to St. Louis to talk to the local user

# July 30, 2007 4:56 PM

Nathan said:

Nice example Scott.

Here's another great discussion about the design pattern presented here.

polymorphicpodcast.com/.../mv%2Dpatterns

Enjoy!

# September 23, 2007 11:13 PM

Chris May said:

Scott,

I just finished listening to your DNR interview.  

The one thing you mentioned that I had not considered was the reuse of a presenter.  Your example was: you would need a presenter to fetch and display a set of questions, but you could then reuse that presenter for a page to edit those questions because you still need to fetch and display them.

In this type of reuse, would you define more than 1 type of presenter in the Init of the webfore (i.e. fetchPresenter and editPresenter) and then call into each one depending on the situation?

# October 17, 2007 10:28 AM

scott cate said:

Chris May,

You have to ask this question. Are you ever going to use the updatePresenter in a place that the readPresenter is not used?

Two scenarios, two solutions. Let's say you decide that they're always going to be coupled. You think that the edit form, always needs to be read first, to supply the original values. In this case you can use inheritance and the updateView and inherit from the readView.

This breaks down when you look at the single point of responsibility though. now you have a presenter that forces you to both do reads and updates.

And it breaks when you want to do something like a web service that takes data for an update. The web service shouldn't be forced to fetch the data first to update it.

So I keep the read and the update as separate concerns. Then yes, to answer your question, I establish the null presenter in the body of the page

(same place as ... private ContactUsPresenter presenter; in the above code example)

Then you can initialize them in the oninit, or closer to the point of use.

# October 19, 2007 6:14 AM

Chris May said:

Thanks Scott!

# October 19, 2007 1:57 PM

The Usual Dosage » Post Topic » Why MVP Is and Isn???t the Answer said:

Pingback from  The Usual Dosage  &raquo; Post Topic   &raquo; Why MVP Is and Isn???t the Answer

# November 27, 2007 10:41 AM

Amyo Kabir said:

This is really a very helpful example.

MVP >>now seems very easy for me to implement.

Thanks

# December 12, 2007 12:41 PM

Ante said:

Never call the presenter direct like you are doing with presenter.ProcessForm();.

So instead of this direct call. Create an eventhandler.

The presenter subscribes on this event that the page code behind makes.

You want a loose connection between the UI and presenter. For nunit testing purposes.

For the validation you can use validation on the page that is connected to validation on the domain objects.

Use the enterprise validation.

A validation is made before saving the anything to layers below.

Then a validation can be made in lower layers also. If access to lower layers through other ways than the presenter. Maybe through web services.

In some cases a direct validation can be preferred in the UI. So that the user does not have to fill in everything and then notice what is missing.

But every pattern can be adjusted for your own special needs. It is all up to you.

# January 27, 2008 1:35 PM

ASP.NET MVC Archived Buzz, Page 1 said:

Pingback from  ASP.NET MVC Archived Buzz, Page 1

# July 2, 2008 2:10 AM

ASP.NET MVC Archived Blog Posts, Page 1 said:

Pingback from  ASP.NET MVC Archived Blog Posts, Page 1

# July 2, 2008 7:10 AM

Tnahsiv said:

How can we create a test case with this example using NUnit ?

# September 19, 2008 5:32 AM

Gourav Shrivastava said:

Hi, I am new in MVP, I have a question here, Can i use DTO here insteed of Interfaces or why didn't you use DTP here because DTO common amoung all the layers.  

# January 28, 2009 4:05 AM

scott cate said:

Technically you can use a DTO, or anything else that would create your contract. BUT ... it's a bad idea. If you use a DTO you're forced to actually have an object to send around.

The reason the Interface is so nice is because you don't know (or care) about the implementation, you just care that it is implemented.

# January 28, 2009 10:34 AM

Jandler said:

Hello,

If I don't use a DTO, how would I display things like a grid or a list? I would kinda need to pass some kind of object because transforming all that do simple type is going to be a bit messy. I was thinking of something in the line of list<Customer> for example. Also, I think that would fall within the line of the ViewModel idea that is being toss around in the past couple of years.

# June 10, 2009 4:59 PM
Leave a Comment

(required) 

(required) 

(optional)

(required)