2012-10-16 12 views
7

Ancora un po 'nuovo per ASP.net e ho questo strano problema. È uno scenario molto semplice ma qualcosa è successo e non riesco a capirlo. La distribuzione dovrebbe restituire una vista denominata Distribuzione che viene digitata nel modello CompiledAppModel. Tuttavia, quando si fa clic su Installa nella vista, non esce mai dalla pagina nonostante venga chiamato il metodo Return(). Qualche idea?Il controller ASP.net MVC non restituirà la vista

Ecco il mio controller:

[HttpPost] 
public ActionResult Deploy(string key_name, string custom_folder = "") 
{ 
    string userId = Membership.GetUser().ProviderUserKey.ToString(); 
    UserDataModel user_info = _user_data_service.getUserDataByPrimaryIDNoDB(userId, HttpContext.Cache); 
    log.Trace("Deploy was called. key_name:" + key_name + " UID: " + user_info.UID); 

    // first we'll call the info to install remote application 
    bool serviceInstall = _fms_app_service.DeployFmsApp(user_info, key_name, custom_folder); 

    // then we'll call to generate client side info 
    bool clientInstall = _fms_app_service.CompileClientApp(user_info, key_name); 

    var model = _fms_app_service.getInstalledAppInfo(user_info, key_name); 
    if (serviceInstall && clientInstall) 
    { 
     return RedirectToAction("Deploy", model); 
    } 

    return View("Error"); 
} 

e mio punto di vista:

@model IEnumerable<Models.Applications.FmsAppModel> 

@foreach (var item in Model) { 
    <div class="col"> 
     <h2>@Html.DisplayFor(modelItem => item.friendly_name)</h2> 
     <p>@Html.DisplayFor(modelItem => item.app_description)</p> 
     <p><strong>Tags:</strong> @Html.DisplayFor(modelItem => item.app_type)</p> 

     <a href="#" class="btn btn-primary install-app" data-key-name="@(item.key_name)">Install</a> 

     @Html.ActionLink("Details", "Detailss", new { id=item.app_id }) 
    </div> 
} 
</div> 

<script type="text/javascript"> 
    (function() { 
     $('.install-app').on('click', function (e) { 
      e.preventDefault(); 
      var data_key_name = $(this).data('key-name'); 
      //ajax install app 
      $.ajax({ 
       type: "POST", 
       url: '@Url.Action("Deploy")', 
       data: { 
        key_name: data_key_name 
       } 
      }); 
     }); 
    })(); 
</script> 

E il modello.

public class CompiledAppModel 
{ 
    [Display(Name = "Admin URL")] 
    public string adminURL { get; set; } 

    [Display(Name = "Viewer URL")] 
    public string viewerURL { get; set; } 

    [Display(Name = "Embed URL")] 
    public string embedURL { get; set; } 
} 

risposta

4

Suppongo che tu voglia veramente reindirizzare dopo aver effettuato la chiamata ajax.

Per quanto ne so, è necessario implementare un ActionResult personalizzato, qualcosa di simile:

public class AjaxAwareRedirectResult : RedirectResult 
{  
    public AjaxAwareRedirectResult(String url) 
     : base(url) 
    { 
    } 

    public override void ExecuteResult(ControllerContext context) 
    { 
     if (context.RequestContext.HttpContext.Request.IsAjaxRequest()) 
     { 
      String destinationUrl = UrlHelper.GenerateContentUrl(Url, context.HttpContext); 

      JavaScriptResult result = new JavaScriptResult() 
      { 
       Script = "window.location='" + destinationUrl + "';" 
      }; 
      result.ExecuteResult(context); 
     } 
     else 
     { 
      base.ExecuteResult(context); 
     } 
    } 
} 

nel controller, basta fare:

[HttpPost] 
public ActionResult Deploy(string key_name, string custom_folder = "") 
{ 
    string userId = Membership.GetUser().ProviderUserKey.ToString(); 
    UserDataModel user_info = _user_data_service.getUserDataByPrimaryIDNoDB(userId, HttpContext.Cache); 
    log.Trace("Deploy was called. key_name:" + key_name + " UID: " + user_info.UID); 
    // first we'll call the info to install remote application 
    bool serviceInstall = _fms_app_service.DeployFmsApp(user_info, key_name, custom_folder); 
    // then we'll call to generate client side info 
    bool clientInstall = _fms_app_service.CompileClientApp(user_info, key_name); 

    var model = _fms_app_service.getInstalledAppInfo(user_info, key_name); 
    if (serviceInstall && clientInstall) 
    { 
     return RedirectToAction("Deploy", model); 
    } 
    return AjaxAwareRedirectResult("/foo"); 
} 

Ma, come ho detto, questo è suppongo solo che tu voglia veramente reindirizzare dopo la chiamata Ajax.

1

mi sembra vostro usando una chiamata AJAX per fare il vostro messaggio al server, nel qual caso il risultato non sta per essere reso alla pagina senza un po 'di lavoro extra. È possibile definire un gestore di successo sulla chiamata ajax per agire quando viene restituita la chiamata ajax. Quindi, qualcosa di simile a

<script type="text/javascript"> (function() { 
    $('.install-app').on('click', function (e) { 
     e.preventDefault(); 
     var data_key_name = $(this).data('key-name'); 
     //ajax install app 
     $.ajax({ 
      type: "POST", 
      url: '@Url.Action("Deploy")', 
      data: { 
       key_name: data_key_name 
      }, 
      success: function(data) { alert(data) } 
     }); 
    }); 
})(); 

vi darà un messaggio di avviso con il codice HTML restituito dalla chiamata AJAX quando la richiesta viene completata.

Userò anche Firebug o gli strumenti di sviluppo in Chrome per visualizzare l'HTML restituito, se sul server si verifica un'eccezione dovresti essere in grado di ispezionarlo in modo più dettagliato utilizzando questi strumenti.

1

Fare un reindirizzamento HTTP dopo una chiamata Ajax potrebbe non avere molto senso. Potresti farlo semplicemente con un modulo html e un POST regolare.

Tuttavia, se si ha realmente bisogno Reindirizzamento e vuole ancora la post attraverso AJAX si poteva farlo restituendo JSON invece di un redirect, come suggerito nei seguenti risposte:

In tal caso, è possibile restituire l'URL dell'azione di destinazione all'interno di un oggetto Json e utilizzare tali informazioni nel gestore del successo come mostrato nella risposta di Neil.

Inoltre, ricorda che RedirectToAction è solo un redirect 302, di conseguenza, non sarà il rendering direttamente la vista in modo da non passare un ViewModel in piena regola, solo l'azione URL per il browser o il rilascio del GET .

Tale azione GET target deve essere quella responsabile per ottenere l'App Info installata e passarla come parametro a una vista, seguendo lo POST-REDIRECT-GET pattern.

Problemi correlati