tags:

views:

269

answers:

3

SHORT:
How do I make a controller return the current view or just simply do nothing?

LONG:
I have a partial view where i've created an imageslider. It contains a link which sends a request to a controller to get the next image (using ajax). The controller fetches the next image, stores it in ViewData and sends back a partial view (the one above).

Now, what I do today is that when the controller reaches the last image it re-return the very same image (by refetching it), but still creates a new view, that is, the client/browser re-parses the "same" data.
This seems somewhat non-optimal.

What I'd like to do is that when controller reaches the last image it should simply do nothing.
If I return null then the view is updated with empty contents.
I want the view/client/browser to retain whatever it has and the controller to simply do nothing.

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult GetNextImage(...)
    {
        if(Request.IsAjaxRequest())
        {
            if(CURRENT_IMAGE != LAST_IMAGE)
            {
                Image image = GetNextImage(...);
                var partialViewResult = new PartialViewResult();
                partialViewResult.ViewName = "ImageSlide";
                partialViewResult.ViewData.Model = image;
                return partialViewResult;
            }
            else
            {
                // DO NOTHING, HOW?
            }
        }

        return RedirectToAction("Error", "Home");
    }
+2  A: 

You can return an EmptyResult if you want it to do nothing...

return new EmptyResult();

If you're using the AjaxHelper you can avoid the update by supplying an unsuccessful status code (e.g. 404 or whatever is most appropriate), that'll stop it replacing your div as the javascript in MicrosoftMvcAjax.js explicitly checks for a successful response before updating any elements:-

this.ControllerContext.HttpContext.Response.StatusCode = 404;
return new EmptyResult();

Ultimately the best way to avoid it is to design the partial view so it avoids the problem in the first place (like you mention yourself).

sighohwell
Well actully it does something, it returns an empty result.Same as returning null.This simply shows empty content.That is not what I want it to do.I want it to.. hmm.. do nothing, bail out, leave current view as is.No update. :)
Dent Argue
Well you're calling it via AJAX so it has to receive a response from the XMLHttpRequest? Just check the length of the result in the success callback and if it's greater than 0 replace the contents with your new HTML fragment otherwise leave it as is.
sighohwell
I'm using the "built-in" ajax:<%= Ajax.ActionLink("Next", "GetNextImage", "Image", new { ... }, new AjaxOptions { InsertionMode = InsertionMode.Replace, UpdateTargetId = "ImageDiv" })%>Was hoping for a simple solution with no need for gritty javascripting etc.
Dent Argue
A: 

Assuming that you are using MicrosoftMvcAjax, you could send back a JavascriptResult that alerts the user that they have reached the end of the slider. If the response is javascript rather than content, the MicrosoftMvcAjax handler executes it instead of replacing the DOM contents.

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult GetNextImage(...)
{
    if(Request.IsAjaxRequest())
    {
        if(CURRENT_IMAGE != LAST_IMAGE)
        {
            Image image = GetNextImage(...);
            var partialViewResult = new PartialViewResult();
            partialViewResult.ViewName = "ImageSlide";
            partialViewResult.ViewData.Model = image;
            return partialViewResult;
        }
        else
        {
            return JavaScript( "alert('No more images');" );
        }
    }

    return RedirectToAction("Error", "Home");
}

Of course, you'd probably want to be more creative and use the jQuery dialog plugin or something rather than an alert.

tvanfosson
A: 

Ok, I've got it.
Not a solution to my question but still solves the problem.

I'll simply not show the "Next" link when the view shows the last image.

Can't believe I didn't think of it earlier...

Thanks for your efforts guys

Dent Argue