web-dev-qa-db-fra.com

Les actions enfants ne sont pas autorisées à effectuer des actions de redirection, après avoir défini le site sur HTTPS.

Je reçois l'erreur ci-dessous:

Child actions are not allowed to perform redirect actions.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: Child actions are not allowed to perform redirect actions.

Source Error:

    Line 1:  <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<RenderActionViewModel>" %>
    Line 2:  <%Html.RenderAction(Model.ActionName, Model.ControllerName, Model.RouteValues); %>
    Line 3: 



The Stack trace is:

    [InvalidOperationException: Child actions are not allowed to perform redirect actions.]


    System.Web.Mvc.RedirectResult.ExecuteResult(ControllerContext context) +700064
       System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +727764
       System.Web.Mvc.Controller.ExecuteCore() +159
       System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +334
       System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +62
       System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +15
       System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +52
       System.Web.Mvc.<>c__DisplayClass4.<Wrap>b__3() +15
       System.Web.Mvc.ServerExecuteHttpHandlerWrapper.Wrap(Func`1 func) +41
       System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride) +1411

    [HttpException (0x80004005): Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'.]
       System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride) +2819
       System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage) +275
       System.Web.HttpServerUtilityWrapper.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm) +94
       System.Web.Mvc.Html.ChildActionExtensions.ActionHelper(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues, TextWriter textWriter) +828
       System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues) +56
       ASP.views_shared_renderaction_ascx.__Render__control1(HtmlTextWriter __w, Control parameterContainer) in c:\TFS\PEEP\Src\Main\Hosts\BCA.PEEP.WebSite\Views\Shared\RenderAction.ascx:2
       System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +131
       System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +150
       System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +12742749
       System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +249
       System.Web.UI.Page.Render(HtmlTextWriter writer) +40
       System.Web.Mvc.ViewPage.Render(HtmlTextWriter writer) +65
       System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +150
       System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +12742749
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5363

Le code RenderAction.ascx où j'obtiens l'erreur à la ligne 2 est:

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<RenderActionViewModel>" %>
    <%Html.RenderAction(Model.ActionName, Model.ControllerName, Model.RouteValues); %>

Et l'action dans le contrôleur est:

public ViewResult DashboardQuicksearch(UserFilter userFilter, bool? showAdvancedSearchLink)
        {
            int resultCount;
            List<KeyInfo<string>> makeList = quickSearchProvider.GetKeysForCriteriaKey(SearchType.Vehicle, "MakeName", userFilter, "null", false, null, out resultCount);

            var selectListItems = new List<SelectListItem>();
            foreach (KeyInfo<string> item in makeList)
            {
                selectListItems.Add(new SelectListItem() { Text = item.Key, Value = item.Key, Selected = false });
            }

            var viewModel = new DashboardQuicksearchViewModel() {
                MakeList = (makeList.Count == 1)
                    ? new SelectList(selectListItems, "Value", "Text", selectListItems[0].Value)
                    : new SelectList(selectListItems, "Value", "Text"),
                VehicleCount = quickSearchProvider.GetLotItemCount("null", userFilter),
                ShowAdvancedSearchLink = (showAdvancedSearchLink.HasValue ? showAdvancedSearchLink.Value : false)
            };

            return View(Constants.Views.Search.DashboardQuicksearch, viewModel);
        }

Je ne sais absolument pas comment le réparer.

MODIFIER :

C'est le DashboardQuickSearch.ascx

<%@ Control Language="C#" Inherits="BCA.PEEP.Web.UI.ViewUserControlBase<DashboardQuicksearchViewModel>" %>
<%@ Import Namespace="BCA.PEEP.Web.Mvc" %>


<div class="Makes">
<%:(Model.MakeList.Count() == 1 
    ? Html.DropDownList("Makes", Model.MakeList, new {@class="search-select"})
    : Html.DropDownList("Makes", Model.MakeList, Html.Text("Name of search results filter:SelectMake"), new {@class="search-select"})
    ) %>
</div>
<div class="Models"><%:Html.DropDownList("Models", new List<SelectListItem>(), Html.Text("Name of search results filter:SelectModel"), new { disabled = "disabled", @class="search-select"})%></div>
<div class="ResultAndAction">
    <span id="VehicleCount" class="VehicleCount"><span class="count-number"><%:Model.VehicleCount.ToString("N0") %></span> <%: Html.Text(Model.VehicleCount, "SearchResultsLabels:Vehicles singular", "SearchResultsLabels:Vehicles plural")%></span>
    <div id="QSButtonDiv" class="Button">
        <input id="QSButton" type="button" value ="<%:Html.Text("Text on buttons:search")%>" onclick="ExecuteSearch()" disabled="disabled" />
    </div>
<% if (Model.ShowAdvancedSearchLink) { %>
    <div id="ASButtonDiv" class="Button Hidden">
        <input id="ASButton" type="button" value ="<%:Html.Text("Text on links:AdvancedSearch")%>" onclick="AdvancedSearch()" />
    </div>
<% } %>
</div>

<script type="text/javascript">
    $(document).ready(function () {
        var vehiclesSingular = '<%=Html.Text("SearchResultsLabels:Vehicles singular")%>';
        var vehiclesPlural = '<%=Html.Text("SearchResultsLabels:Vehicles plural")%>';
        var makeCount = '<%=Model.MakeList.Count().ToString("N0") %>';

        $('#Makes').change(function () { PopulateModels(); });
        $('#Models').change(function () { UpdateVehicleCount(); });
        $('#Makes').trigger('change');

        function PopulateModels() {
            var make = $('#Makes').val();
            var $models = $('#Models');
            $models.append('<option value="" selected>' + '<%=Html.Text("Name of search results filter:SelectModel") %>' + '</option>');
            //alert("Populate Models - Make = '" + make + "'");
            if (make == '') {
                $models.attr('disabled', 'disabled');
                $models.find('option').remove();
                $models.append('<option value="" selected>' + '<%=Html.Text("Name of search results filter:SelectModel") %>' + '</option>');
                $models.val('');
                UpdateVehicleCount();
                $('#QSButton').attr('disabled', 'disabled');
                $('#QSButtonDiv').removeClass('PrimaryButton').addClass('Button');
                return;
            }

            $.ajax({
                type: 'GET',
                url: '/Search/GetModelsForMake/',
                data: { MakeName: make },
                dataType: "json",
                success: function (results) {
                    $models.find('option').remove();
                    $models.append('<option value="" selected>' + '<%=Html.Text("Labels for vehicle characteristics:All Models") %>' + '</option>');
                    $(results.Models).each(function (index, model) {
                        $models.append('<option value="' + model + '">' + model + '</option>');
                    });                    
                    DisplayVehicleCount(results.VehicleCount);
                }
            });
            $models.removeAttr('disabled');
            $('#QSButton').removeAttr('disabled', 'disabled');
            $('#QSButtonDiv').removeClass('Button').addClass('PrimaryButton');
        }

        function UpdateVehicleCount() {
            var make = $('#Makes').val();
            var model = $('#Models').val();

            $.ajax({
                type: 'GET',
                url: '/Search/GetMakeModelCount/',
                data: { MakeName: make, ModelName: model },
                dataType: "json",
                success: function (result) {
                    DisplayVehicleCount(result);
                }
            });
        }

        function DisplayVehicleCount(vehicleCount) {
            var vehicles = (vehicleCount == '1') ? vehiclesSingular : vehiclesPlural;
            $('#VehicleCount').html('<span class="count-number">' + vehicleCount + '</span>' + ' ' + vehicles);
        }

    });

    function ExecuteSearch() {
        var make = $('#Makes').val();
        var model = $('#Models').val();

        if (make == '')
            return;

        window.location = '/Quicksearch/Vehicles?make=' + make + '&model=' + model;
    }

    function AdvancedSearch() {
            <% if(AmbientContextHelper.CurrentBrand.Name.ToLower().Contains("alphabet"))
           { %>
            window.location = '/SearchVehicle';
            <% } else 
           { %>
            window.location = '/Quicksearch/Vehicles';
            <% } %>
        }
</script>
19
Marian Ene

Cela signifie que: 

  1. l'action correspondant à l'URL a été traitée et un résultat de vue a été renvoyé.
  2. Le moteur de vue d'ASP.NET MVC a commencé à rendre la vue, en envoyant éventuellement des en-têtes et une partie du code HTML au navigateur.
  3. le moteur de vue a rencontré un appel RenderAction (...) et a commencé à exécuter l'action.
  4. l'action a tenté de renvoyer un code d'état Redirect HTTP au navigateur

À ce stade, ASP.NET est désemparé: il a déjà commencé à envoyer des en-têtes et du code HTML au client, mais il lui est maintenant demandé de rappeler tout cela et d'envoyer un code d'état de redirection. Évidemment, il ne peut pas faire cela, alors il lève une exception.

Vous devrez comprendre pourquoi une redirection est déclenchée et vous assurer que cela ne se produise pas. La cause la plus probable (mais en aucun cas la seule cause possible) est un filtre d'action personnalisé qui n'a pas été conçu pour prendre en compte les actions enfants. Les filtres d'action ASP.NET MVC vérifient généralement si l'action en cours d'exécution a été appelée en tant qu'action enfant et évitent les redirections dans de tels scénarios.

35
Rune

Le problème était un ActionFilter dans la classe ControllerBase. (je ne l'ai pas vu la première fois)

C'était comme 

[ActionFilters.RequireHttps(RequireSecure = false)]

Je devais le mettre sur "vrai"

Merci à tous pour vos réponses.

Remarque: Représente la classe de base pour tous les attributs de filtre d'action Namespace: System.Web.Http.Filters Assembly: System.Web.Http (dans System.Web.Http.dll)

1
Marian Ene

Vous devriez écrire return PartialView(...) au lieu de return View(...) pour un childAction.

1
Ratul