views:

644

answers:

2

Hi,

I just need to have the a small CMS-like controller. The easiest way would be something like this:

public class HomeController : Controller {
    public ActionResult View(string name) {
        if (!ViewExists(name))
            return new HttpNotFoundResult();
        return View(name);
    }

    private bool ViewExists(string name) {
        // How to check if the view exists without checking the file itself?
    }
}

The question is how to return HTTP 404 if the there is no view available?

Probably I can check the files in appropriate locations and cache the result, but that feels really dirty.

Thanks,
Dmitriy.

+5  A: 
private bool ViewExists(string name) {
    return ViewEngines.Engines.FindView(
        ControllerContext, name, "").View != null;
}
Darin Dimitrov
Darin, that's beautiful! Another thing to consider here: already having an instance of `ViewEngineResult` how is it possible to reuse it so that `ViewResult` won't perform the search again?
Dmytrii Nagirniak
Don't worry about this, when compiled in Release mode view locations are cached.
Darin Dimitrov
Also I believe the view found this way should be properly disposed.
Dmytrii Nagirniak
You will get an `IView` which is not disposable but you have a point here.
Darin Dimitrov
Darin, I have come up with much better solution I think. See my answer. Your helped me to get to that point. Thank a lot.
Dmytrii Nagirniak
A: 

The answer from Darin Dimitrov got me an idea.

I think it would be best to do just this:

public class HomeController : Controller {
    public ActionResult View(string name) {
        return new ViewResultWithHttpNotFound { ViewName = name};
    }
}

having a new type of action result:

    public class ViewResultWithHttpNotFound : ViewResult {

        protected override ViewEngineResult FindView(ControllerContext context) {
            ViewEngineResult result = ViewEngineCollection.FindView(context, ViewName, MasterName);
            if (result.View == null)
                throw new HttpException(404, "Not Found");
            return result;      
        }

    }
Dmytrii Nagirniak