Use the base controllers File method.
public ActionResult Image(string id)
{
var dir = Server.MapPath("/Images");
var path = Path.Combine(dir, id + ".jpg"); //validate the path for security or use other means to generate the path.
return base.File(path, "image/jpeg");
}
As a note, this seems to be fairly efficient. I did a test where I requested the image through the controller (http://localhost/MyController/Image/MyImage
) and through the direct URL (http://localhost/Images/MyImage.jpg
) and the results were:
- MVC: 7.6 milliseconds per photo
- Direct: 6.7 milliseconds per photo
Note: this is the average time of a request. The average was calculated by making thousands of requests on the local machine, so the totals should not include network latency or bandwidth issues.
Your controllers (in the MVC project) should be calling your objects in the Service project. The services project is where all the business logic is handled.
A good example is this:
public ActionResult Index()
{
ProductServices productServices = new ProductServices();
// top 10 products, for example.
IList<Product> productList = productServices.GetProducts(10);
// Set this data into the custom viewdata.
ViewData.Model = new ProductViewData
{
ProductList = productList;
};
return View();
}
or with Dependency Injection (my fav)
// Field with the reference to all product services (aka. business logic)
private readonly ProductServices _productServices;
// 'Greedy' constructor, which Dependency Injection auto finds and therefore
// will use.
public ProductController(ProductServices productServices)
{
_productServices = productServices;
}
public ActionResult Index()
{
// top 10 products, for example.
// NOTE: The services instance was automagically created by the DI
// so i din't have to worry about it NOT being instansiated.
IList<Product> productList = _productServices.GetProducts(10);
// Set this data into the custom viewdata.
ViewData.Model = new ProductViewData
{
ProductList = productList;
};
return View();
}
Now .. what's the Service project (or what is ProductServices)? that's a class library with your business logic. For example.
public class ProductServices : IProductServices
{
private readonly ProductRepository _productRepository;
public ProductServices(ProductRepository productRepository)
{
_productRepository = productRepository;
}
public IList<Product> GetProducts(int numberOfProducts)
{
// GetProducts() and OrderByMostRecent() are custom linq helpers...
return _productRepository.GetProducts()
.OrderByMostRecent()
.Take(numberOfProducts)
.ToList();
}
}
but that might be all so hardcore and confusing... so a simple version of the ServiceProduct class could be (but i wouldn't really recommend) ...
public class ProductServices
{
public IList<Product> GetProducts(int numberOfProducts)
{
using (DB db = new Linq2SqlDb() )
{
return (from p in db.Products
orderby p.DateCreated ascending
select p).Take(10).ToList();
}
}
}
So there you go. You can see that all the logic is in the Service projects, which means u can reuse that code in other places.
Where did i learn this?
From Rob Conery's MVC StoreFront media and tutorials. Best thing since sliced bread.
His tutorials explain (what i did) in good detail with full solution code examples. He uses Dependency Injection which is SOO kewl now that i've seen how he uses it, in MVC.
HTH.
Best Answer
Business logic should really be in the model. You should be aiming for fat models, skinny controllers.
For example, instead of having:
I would rather have:
This assumes that tax is calculate by an external service, and requires your model to know about interfaces to your external services.
This would make your controller look something like:
Or something like that.