views:

43

answers:

1

One of the beauties of MVC is the ability to use Actions for both normal web calls as well as Ajax calls. But in doing so, I'm a little uncomfortable with my code. I'd like to know what other people think.

So I want to view the details of an item in a list. I have created a Details view. I also have decided to use hijaxing -- if a user has Javascript enabled, I want the Details form to be a popup. So for the Details.aspx, I need full html, but if it's an ajax request, I only need the form elements. So here's how I wrote my controller method:

public ActionResult Details(int id)
{
    if (Request.IsAjaxRequest())
    {
        return PartialView(GetAjaxModel());
    }
    else
        return View(GetModel());
}

It works, but whenever I have a giant "if" statement surrounding my entire code, it bothers me. How can I get rid of that and/or make the code better?

I could also write a separate method called AjaxDetails, but what I'd really like to write is this:

public ActionResult Details(int id)
{
        return View(GetModel());
}

[Ajax]
public ActionResult Details(int id)
{
    return View(GetAjaxModel());
}    

But to my knowledge, there's no attribute to filter Ajax vs normal calls.

How do you write your Ajax calls?

UPDATE Clicktricity does indeed have the correct answer. One additional change, however is that that since 2 controller methods cannot have the same signature, I need to write the controller code as such:

public ActionResult Details(int id)
{
        return View(GetModel());
}

[AjaxRequest]
[ActionName("Details")]
public ActionResult DetailsAjax(int id)
{
    return PartialView(GetAjaxModel());
}    
+3  A: 

You're correct that there isn't a filter that does that - but in a typical MVC fashion, there is no reason why you couldn't write your own.

public class AjaxRequestAttribute : ActionMethodSelectorAttribute
{
    public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
    {
        return (controllerContext.HttpContext.Request.IsAjaxRequest())
    }
}

Then you can use [AjaxRequest] on your action methods.

(Please note, I haven't tested this)

Clicktricity
+1 for the answer, and the accompanying caveat!
Dan Atkinson