3

I want to make my Actions in Controllers more flexible. I mean that common Action usually returns:

...
return View("someView");

or, for example, if Ajax:

...
return Json(new {result="ok"});

What I want is to make my Actions more "multipurpose". For example, I made my UI layer based on simple non-Ajax requests, then I decided to make it more user-friendly and added some Ajax. That way I must correct a little a lot of Actions to return Json.

The most simplest (and probably the worst) way to avoid such things is to write the following code in every (or almost every) Action:

if (Request.IsAjaxRequest) {
    return Json(new {result="ok"});
}
else { 
    return View("someView") 
}

But of course such method completely conflicts with DRY's principles.

So I want to find the good practice to achieve that "multipurposing".

One way is to write some helper method like that:

public ActionResult CheckForAjax(ActionResult result)
{
  return ActionResult(result, Json(new {result="ok"}));
}

public ActionResult CheckForAjax(ActionResult result, Json json)
{
  if (Request.IsAjaxRequest) {
     return json;
  }
  else {
     return result;
  }
}

Such way I can call helpers in Actions:

return CheckForAjax(View(...));

or

return CheckForAjax(View(...), Json(new {myCustomJson="hi"});

But I don't know if it's good way or just reinventing some bicycle :) Maybe it's better to use Actions Filters? But I don't know how to pass custom Json to that filter...

Thank you for any suggestions

1
  • 1
    Your original solution is better because it is explicit. Commented Mar 29, 2012 at 19:26

2 Answers 2

6

To be honest I think that your original solution is fine, and your second is more of a violation of DRY than the first. Your second solution is very redundant, and provides two methods to do a job easily handled by one.

This is not only poor style, but also a maintainability issue. By having two functions for one purpose, you have to update both functions every time there is a change. It is also not extremely clear why you're doing it that way, which will make it difficult for other developers to maintain your code.

If you ask me, KISS (keep it simple stupid) is more important than DRY (don't repeat yourself). If your code is easily understood, then it is good code.

Sign up to request clarification or add additional context in comments.

Comments

2

If you return the same models from an action, such that:

var model = new {result="ok"}
if (Request.IsAjaxRequest) {
    return Json(model);
}
else { 
    return View("someView", model) 
}

You could easily write an Actionfilter to do this. Example follows:

protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);

        if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
        {
            var res = filterContext.Result as ViewResultBase;
            if (res == null) { return; }


            var jres = new JsonNetResult();
            jres.SerializerSettings.Converters.Add(new IsoDateTimeConverter());
            jres.Data = res.ViewData.Model;
            filterContext.Result = jres;
        }
    }

Note that this method means that you are returning the same model from the action. Whether you choose to consume the result object in the view in a 'Normal' request is up to you.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.