Darren
Darren

Reputation: 11021

Clarity about helpers in MVC3?

Are helpers in MVC3 used in the controller as well as the views?

Is a helper the right place to put commonly used controller methods?

I want to create a common method to get all sub children IDs in a database and make sure it is in the right area. I just want to make sure I am putting my logic in the right area.

Thanks

Upvotes: 4

Views: 122

Answers (4)

StriplingWarrior
StriplingWarrior

Reputation: 156748

The HtmlHelper is not available to the controller, because the controller should not be responsible for generating HTML, but the UrlHelper is available within the controller.

A method to get specific data from your database does not belong in your controller, or in a UrlHelper or an HtmlHelper. You should create a separate class for this logic, and then call the method on this class from within your controller. If you are using Dependency Injection, which I suggest, your controller code might look like this:

public class MyController
{
    IMyDataUtil _dataUtil;
    public MyController(IMyDataUtil dataUtil)
    {
        _dataUtil = dataUtil;
    }

    public ActionResult SomeAction(int parentId)
    {
        var childIds = _dataUtil.GetChildIds(parentId);
        ...
    }
}

As you can see, this allows you to keep the data-access code in a class specifically designed for that purpose. The fact that this controller depends on that utility class is immediately obvious, and doesn't take that much more code than calling an extension method on a helper. Controllers that don't deal with that class's methods won't need to have it available.

On the other hand, if there are methods that are likely to be used by a bunch of different controllers, injecting this same data class into all of them may become cumbersome. In that case, you could:

  1. Extend a base class that has an instance of the data-access class injected into it via method or property injection, and which then exposes it to sub-classes via a protected or public property, or
  2. Create your own helper class that wraps the classes and methods you're likely to use in all your controllers, and inject that class so you only have one dependency for a variety of common functions, or
  3. Combine steps 1 and 2.

Upvotes: 2

Rob
Rob

Reputation: 45809

If by "helpers" you're referring to things such as HtmlHelper then, no, these aren't used by the controller as in theory you could take your controllers and re-use them with an entirely different rendering engine (for example WPF) as the controller isn't responsible for rendering.

If you're talking about, as I think you are, helper classes/methods that manipulate your data ready for it to be put into a Model by a Controller and then handed off to a View for presentation, then you could consider a "business logic" layer. For example, if you were talking about (the ever typical) Bank Account example, you could have a:

public class BankAccountService
{
    public IEnumerable<string> GetAllAccountIdsForCustomer(int customerId)
    {
        // Talk to the database here and retrieve the account id's for a customer
    }
    public string GetCustomerName(int customerId)
    {
        // Talk to the database here and retrieve the customer's name
    }
}

Your controller would then:

public ActionResult AccountNumbers(int customerId)
{
    var model = new AccountNumbersModel();
    model.CustomerId = customerId;
    model.AccountNumbers = BankAccountService.GetAllAccountIdsForCustomer(customerId);

    return View(model);
}

Obviously in this example you'd need to have a class called AccountNumbersModel defined and you'd also probably want to consider using Dependency Injection to provide an instance of BankAccountService to your controller, but describing how to go about all that is kinda outside the scope of this answer.

The advantages this approach gives you are testability and separation, each piece of code is responsible for one task, and you reduce the complexity of each individual piece and make it easier to make changes without breaking things.

Upvotes: 1

ten5peed
ten5peed

Reputation: 15900

I want to create a common method to get all sub children IDs in a database and make sure it is in the right area. I just want to make sure I am putting my logic in the right area.

That sounds like a job for an ActionFilter.

Upvotes: 0

Daniel A. White
Daniel A. White

Reputation: 191058

You could implement a base Controller for that logic. Helpers, or extension methods, are good for when you don't want to change the interface for something.

Upvotes: 4

Related Questions