Nice way to validate Ajax request and return Json in ASP.NET MVC
I want my actions in controllers to be more flexible. I mean, a generic action usually returns:
...
return View("someView");
or, for example, if Ajax:
...
return Json(new {result="ok"});
I want to make my actions more "multifunctional". For example, I created my UI layer based on simple non-Ajax requests, then I decided to make it more user-friendly and added Ajax. So I have to fix a small amount of action to get the Json back.
The easiest (and probably the worst) way to avoid things like this 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, this method is completely contrary to dry principles.
So I want to find a good practice to achieve this "multiplayer mode".
One way is to write a helper method:
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;
}
}
In this way, I can call helpers in Actions:
return CheckForAjax(View(...));
or
return CheckForAjax(View(...), Json(new {myCustomJson="hi"});
But I don't know if this is good or just reinventing the wheel :) Maybe it is better to use Actions Filters? But I don't know how to pass custom Json to this filter ...
Thanks for any suggestions
source to share
To be honest, I think your original solution is fine and your second is more of a DRY violation than the first. Your second solution is very redundant and provides two methods for doing a job that is easily handled by one.
This is not only bad style but also a maintainability issue. With two functions for the same purpose, you must update both functions every time a change occurs. It is also not entirely clear why you are doing this, making it difficult to work with other developers.
If you ask me, KISS (keep it simple stupid) is more important than DRY (don't repeat yourself). If your code is easy to understand, then this is good code.
source to share
If you return the same models from an Activity as:
var model = new {result="ok"}
if (Request.IsAjaxRequest) {
return Json(model);
}
else {
return View("someView", model)
}
You can easily write an Actionfilter to do this. Example:
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 an activity. Whether you choose to use the View Result object in a Normal query is up to you.
source to share