Хороший способ проверки Ajax-запроса и возврата результата Json в ASP.NET MVC - PullRequest
3 голосов
/ 29 марта 2012

Я хочу сделать свои действия в контроллерах более гибкими. Я имею в виду, что обычное действие обычно возвращает:

...
return View("someView");

или, например, если Ajax:

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

Что я хочу, так это сделать мои Действия более «многоцелевыми». Например, я создал слой пользовательского интерфейса на основе простых не-Ajax-запросов, затем решил сделать его более удобным для пользователей и добавил немного Ajax. Таким образом, я должен немного исправить действия, чтобы вернуть Джсона.

Самый простой (и, вероятно, худший) способ избежать подобных вещей - написать следующий код в каждом (или почти каждом) действии:

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

Но, конечно, такой метод полностью противоречит принципам DRY.

Итак, я хочу найти хорошую практику для достижения этого «многоцелевого».

Один из способов - написать такой вспомогательный метод, как этот:

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;
  }
}

Так я могу вызвать помощников в действиях:

return CheckForAjax(View(...));

или

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

Но я не знаю, хороший ли это способ или просто изобретать велосипед :) Может быть, лучше использовать фильтры действий? Но я не знаю, как передать пользовательский Json в этот фильтр ...

Спасибо за любые предложения

Ответы [ 2 ]

6 голосов
/ 29 марта 2012

Если честно, я думаю, что ваше оригинальное решение в порядке, а ваше второе - скорее нарушение СУХОГО, чем первое. Ваше второе решение очень избыточно и предоставляет два метода для выполнения работы, легко выполняемой одним.

Это не только плохой стиль, но и проблема ремонтопригодности. Имея две функции для одной цели, вы должны обновлять обе функции каждый раз, когда происходит изменение. Также не очень понятно, почему вы делаете это так, что другим разработчикам будет сложно поддерживать ваш код.

Если вы спросите меня, KISS (пусть это будет просто глупо) важнее, чем DRY (не повторяйте себя). Если ваш код легко понять, то это хороший код.

2 голосов
/ 29 марта 2012

Если вы возвращаете те же модели из действия, например:

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

Вы можете легко написать Actionfilter для этого. Пример следует:

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;
        }
    }

Обратите внимание, что этот метод означает, что вы возвращаете ту же модель из действия. Вы решите, использовать ли объект результата в представлении в обычном запросе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...