2012-10-16 15 views
7

Wciąż trochę nowego w ASP.net i mam ten dziwny problem. Jest to bardzo podstawowy scenariusz, ale coś jest nie tak i nie mogę tego rozgryźć. Deploy powinien zwrócić widok o nazwie Deploy, który jest wpisany do modelu CompiledAppModel. Jednak po kliknięciu instalacji w widoku nigdy nie opuszcza ona strony mimo wywołania metody Return View(). Jakieś pomysły?ASP.net Kontroler MVC nie zwróci widoku

Oto mój kontroler:

[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"); 
} 

i mój widok:

@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> 

A model.

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

Odpowiedz

4

Zakładam, że naprawdę chcesz przekierować po wywołaniu ajax.

O ile mi wiadomo, trzeba zaimplementować niestandardową ActionResult, coś takiego:

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

w kontroler, tak zrobić:

[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"); 
} 

Ale, jak powiedziałem, to jest tylko ja zakładając, że naprawdę chcesz przekierować po wywołaniu ajax.

1

Wygląda mi na to, używasz wywołanie AJAX, aby zrobić swoje stanowisko z powrotem do serwera, w tym przypadku wynik nie dostanie renderowane do strony bez trochę dodatkowej pracy. Możesz zdefiniować obsługę sukcesu w wywołaniu ajax, aby podjąć działanie, gdy wywołanie ajax wywoła. Więc coś

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

daje komunikat ostrzegawczy z HTML powrocie z wywołania AJAX, gdy żądanie zakończy.

Użyłbym również narzędzia Firebug lub narzędzi programistycznych w przeglądarce Chrome do wyświetlenia zwróconego kodu HTML. Jeśli na serwerze wystąpił wyjątek, należy sprawdzić te szczegóły za pomocą tych narzędzi.

1

Wykonywanie przekierowania HTTP po wywołaniu ajaxa może nie mieć większego sensu. Można to zrobić po prostu za pomocą formularza html i zwykłego testu POST.

Jednakże, jeśli naprawdę potrzebujesz przekierowywanie i nadal chcą POST poprzez AJAX można zrobić go przez powrót JSON zamiast przekierowania, jak zasugerowano w następujących odpowiedzi:

W takim przypadku możesz zwrócić docelowy adres URL akcji w obiekcie Json i użyć tych informacji w swojej procedurze obsługi sukcesu, jak pokazano w odpowiedzi Neila.

Pamiętaj też, że RedirectToAction to tylko przekierowanie 302, więc nie wyświetli widoku bezpośrednio, więc nie przekażesz go pełnowymiarowemu ViewModel, tylko URL działania przeglądarki, aby wydać polecenie GET .

Ta docelowa akcja GET powinna być odpowiedzialna za uzyskanie informacji o zainstalowanej aplikacji i przekazanie jej jako parametru do widoku, zgodnie z POST-REDIRECT-GET pattern.

Powiązane problemy