Asp.Net MVC2 RenderAction меняет тип пантомимы страницы? - PullRequest
13 голосов
/ 15 марта 2010

Похоже, что вызов Html.RenderAction в приложениях Asp.Net MVC2 может изменить тип mime страницы, если тип дочернего действия отличается от типа родительского действия.

Приведенный ниже код (тестирование в MVC2 RTM), который мне кажется разумным, при вызове Home/Index вернет результат типа application/json. Вместо того, чтобы отображать страницу, браузер закроет и спросит вас, хотите ли вы ее загрузить.

Мой вопрос: я что-то упустил? Это ошибка? Если так, какой лучший обходной путь?

Контроллер:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewData[ "Message" ] = "Welcome to ASP.NET MVC!";

        return View();
    }

    [ChildActionOnly]
    public JsonResult States()
    {
        string[] states = new[] { "AK", "AL", "AR", "AZ", };

        return Json(states, JsonRequestBehavior.AllowGet);
    }
}

вид:

<h2><%= Html.Encode(ViewData["Message"]) %></h2>
<p>
    To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
</p>
<script>
  var states = <% Html.RenderAction("States"); %>;
</script>

Ответы [ 6 ]

8 голосов
/ 16 ноября 2010

Я считаю это ошибкой. Если это визуализируемое действие child , то почему оно изменит ответ действия parent ? То же самое происходит с Html.Action, который переводит его в строку. Мой обходной путь делает:

Html.ViewContext.HttpContext.Response.ContentType = "text/html";

после вызова Html.Action. Я полагаю, что кто-то может написать расширение Html Helper оболочки, что-то вроде:

var aux = Html.ViewContext.HttpContext.Response.ContentType;
Html.Action(....); // or Html.RenderAction(...)
Html.ViewContext.HttpContext.Response.ContentType = aux;
8 голосов
/ 15 марта 2010

Это не ошибка.Предполагается, что тип JsonResult устанавливает результат в JSON, потому что это обычно то, что вам нужно.

Вам не нужен JSON результат здесь, вам нужен JSON строка .Так почему бы просто не написать это?

[NonAction]
public string States()
{
    string[] states = new[] { "AK", "AL", "AR", "AZ", };

    return new JavaScriptSerializer().Serialize(states);
}
4 голосов
/ 14 октября 2011

Вы что-то не упускаете (если я не слишком), и я думаю, что это ошибка. У меня такая же проблема в ASP.NET MVC3.

У нас есть действие контроллера, которое возвращает контент из простой системы управления контентом. CMS позволяет пользователю определять тип содержимого возвращаемого содержимого (например, text / plain или text / xml).

Действие контроллера либо вызывается напрямую, либо вызывается как дочернее действие, чтобы позволить представлению содержать управляемые элементы содержимого.

Если часть содержимого создается с типом содержимого «text / plain», и это встроено в представление ASP.NET MVC, тип содержимого родительского элемента переопределяется, и браузер отображает HTML.

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

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

Я уверен, что вы знаете об этом, но в вашем случае я бы предложил явно установить JsonResult.ContentType для типа содержимого родительского элемента.

3 голосов
/ 15 марта 2010

Эту проблему можно решить, явно указав тип mime «back» на text/html:

return Json(states, "text/html", JsonRequestBehavior.AllowGet);

Не похоже, что это должно быть необходимо.

1 голос
/ 22 мая 2013

У меня была проблема сегодня. Причина в том, что мне нужно повторно использовать существующее дочернее действие, чтобы заполнить некоторые данные JSON на странице, чтобы избежать ненужных запросов AJAX.

Основываясь на идее Джейми и Нива, я создал следующий вспомогательный метод.

public static MvcHtmlString ChildAction( this HtmlHelper htmlHelper, ActionResult result )
{
   var aux = htmlHelper.ViewContext.HttpContext.Response.ContentType;
   var actionResult = htmlHelper.Action( result );
   htmlHelper.ViewContext.HttpContext.Response.ContentType = aux;
   return actionResult;
}

Вызовите Html.ChildAction вместо Html.Action, когда вам нужно использовать результат дочернего действия, возвращающего данные json.

1 голос
/ 15 марта 2010

Как и Крейг Штунц сказал тип контента должен измениться.

Лучшим подходом было бы вызвать это действие с помощью AJAX, а затем присвоить возвращаемый объект переменной states в коде JavaScript.

...