1

Question: Comment coder l'URL transmise à javascript pour que dans la version intégrée/déployée le code aller au contrôleur/action avec l'ID et retourner les données JSon, comme cela fonctionne dans l'environnement Visual Studio?URL Problème de routage avec Javascript (Jquery) appel à MVC3 Controller/Action/ID, renvoyer 404, devrait obtenir JSon

Objectif: pour renvoyer des dates au programme datepicker, car elles seront désactivées. Je m'attends à un retour de tableau JSon de chaînes qui sont des dates qui sont ensuite introduites dans le datpicker.

Pertinence par rapport aux autres: De retour des données JSON un appel au contrôleur/action/ID semble que ce serait une chose commune à faire. Je vois d'autres questions concernant les problèmes de routage, ainsi que JSon, et jQuery semble être un moyen populaire pour améliorer le développement web.

Contexte: J'ai un datepicker jQuery-UI qui appelle un contrôleur/action/ID et renvoie les données JSON au datepicker. Il fonctionne parfaitement lors de l'exécution dans Visual Studio, mais échoue lorsqu'il est créé et déployé dans l'environnement de développement. Le code transmet l'URL générée et transmise à jQuery: /Secure/Validation/getDisabledDates/999

Nous utilisons Umbraco, avec un répertoire appelé/Secure dans la zone Umbraco pour contenir notre code MVC. L'URL que le code essaie alors de générer sur l'environnement de développement est: /Secure/Validation/getDisabledDates/999 Si je regarde l'appel et les erreurs dans Firebug, je vois une erreur pour ce qui suit: POST http://dev.ourcompanyname.com/Secure/Validation/getDisabledDates/999 302 Trouvé (si j'étudie plus loin, je trouve que c'était vraiment un 404, qui a été envoyé à la page d'erreur, et c'est ce qui a été trouvé.)

J'utilise @ Url.Action dans la vue pour obtenir le bon (heureusement) URL de l'action, mais lorsque la requête javascript est faite dans l'environnement Dev, le retour est un 404. Le code entre dans le code javascript et affiche l'URL dans une alerte, ce qui me paraît droit. Le code ne semble pas aller aussi loin que le contrôleur MVC (j'ai essayé d'y mettre un messagebox).

Cela semble dû au fait que le contrôleur n'est pas réellement une page réelle distincte dans un répertoire, car le code MVC est compilé dans une DLL. J'ai entendu cela et c'est logique, mais d'autres personnes dans le monde semblent appeler des contrôleurs, alors je ne suis pas sûr de savoir quel est mon problème ici.

À l'origine, il n'y avait qu'un seul ensemble de dates, donc certains appels de code ne disent que GetDates, mais ensuite il a été divisé par Widget, donc les appels reflètent ByWidget, donc un ID est passé. Tous les appels suivent correctement et le code fonctionne dans Dev. SetDates qui est appelé succès dans la fonction javascript est une autre fonction javascript, mais j'ai mis des alertes dans SetDates, dans l'environnement Dev le code ne va pas si loin, sans doute parce qu'il ne trouvera pas le code dans le ValidationController .

Toutes les suggestions utiles seraient très grandement appréciées!

Spécifications: MvC3, Javascript 1.6.4, Jquery jquery-ui-1.8.17, IIS 7.5, Umbraco 4.7.1, Visual Studio 2010

code Javascript dans le fichier .js séparé:

function getDisabledDatesByWidget(urlGetDisabledDatesByWidget) { 
    alert('urlGetDisabledDatesByWidget = ' + urlGetDisabledDatesByWidget); 
    $.ajax({ 
     //data: {id: id}, 
     type: "POST", 
     async: false, 
     url: urlGetDisabledDatesByWidget, 
     dataType: 'json', 
     success: setDates, 
     constrainInput: true, 
     defaultDate: new Date(defaultCutoff + " 00:00") 
    }); 
} 

Code MVC dans la vue, dans le document fonction prêt:

widgetId = '@ViewBag.WidgetId'; 
    var urlGetDisabledDatesByWidget = '@Url.Action("getDisabledDates", "Validation", new{id = @ViewBag.WidgetId})'; 
    getDisabledDatesByWidget(urlGetDisabledDatesByWidget); 

MVC code dans ValidationController:

[HttpPost] 
public JsonResult getDisabledDates(int id) 
{ 
    List<String> disabledDateStrings = new List<String>(); 
    List<DateTime> _DisabledDateDates = DisabledDateSetup.GetDisabledDateDatesByWidget(id).Value.ToList(); 

    ////Convert disabled dates to string array 
    foreach (DateTime disabledDate in _DisabledDateDates) 
    { 
     disabledDateStrings.Add(disabledDate.ToString("M-d-yyyy")); 
    } 

    ChangeType _changeType = ChangeType.NoChangeType; 
    ChangeDateRangeSetupResponse _dates = DisabledDateSetup.GetValidChangeDateRange(_changeType); 

    return Json(new 
    { 
     disabledDates = disabledDateStrings, 
     startDate = UnixTicks(_dates.Value.BeginDate), 
     endDate = UnixTicks(_dates.Value.EndDate) 
    }); 
} 

Code MVC dans la vue, dans la div:

@Html.TextBoxFor(model => model.SetupDate, new { id = "DisabledDateCalendar"}) 

routage Global asax:

public static void RegisterRoutes(RouteCollection routes) 
{ 
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

    routes.MapRoute(
     "Default", // Route name 
     "{controller}/{action}/{id}", // URL with parameters 
     new { controller = "Account", action = "Index", id = UrlParameter.Optional } // Parameter defaults 
    ); 

} 

Ce que je l'ai fait pour essayer de résoudre ce avant de poster:

Répondre

0

Je ne laisse jamais Razor injecter des données dans mon JavaScript, seulement sémantiquement en HTML. En outre, au lieu d'utiliser Url.Action et ces aides bizarres, que diriez-vous juste de rendre l'URL et le balisage manuellement? MVC semble ajouter beaucoup de méthodes inutiles, plus il est plus facile de lire où les choses vont réellement:

Au lieu de:

@Html.TextBoxFor(model => model.SetupDate, new { id = "DisabledDateCalendar"}) 

Que diriez-vous:

<input type="text" id="DisabledDateCalendar" value="@Model.SetupDate" /> 

Faites votre autre code sémantiquement accessible à partir de JavaScript:

<input type="hidden" id="widgetId" value="@ViewBag.WidgetId" /> 
<input type="hidden" id="urlGetDisabledDatesByWidget" value="/secure/validation/getdisableddates/@ViewBag.WidgetId" /> 

De même, y a-t-il une raison pour que votre AJAX soit synchrone? Faisons que async, et maintenant vous n'avez pas rasoir mélangé avec votre JS:

function getDisabledDatesByWidget(urlGetDisabledDatesByWidget) { 
    var urlGetDisabledDatesByWidget = $('#urlGetDisabledDatesByWidget').val(), 
     widgetId = $('#widgetId').val(); 

    alert('urlGetDisabledDatesByWidget = ' + urlGetDisabledDatesByWidget); 

    $.ajax({ 
     //data: {id: id}, 
     type: "post", 
     url: urlGetDisabledDatesByWidget, 
     dataType: 'json', 
     constrainInput: true, 
     defaultDate: new Date(defaultCutoff + " 00:00") 
    }) 
    .done(setDates); 
} 
+0

Eli, je vous remercie beaucoup pour vos suggestions. J'ai mis en œuvre toutes les suggestions, mais je ne trouve aucun changement notable. Tout fonctionne toujours dans Visual Studio, mais pas dans l'environnement de développement. – Ahliana

+0

Lorsque j'exécute le code dans VS, les modifications que vous avez suggérées fonctionnent correctement. Quand je le déploie, puis l'exécute, il ne parvient toujours pas à obtenir les données. J'ai ajouté JsonRequestBehavior.AllowGet au retour JSon, et dans VS je vois les données retournées, mais dans Dev il renvoie toujours 404. Merci encore pour votre temps et pour toute aide. – Ahliana

+0

La réponse: Nous utilisons des transformations de configuration Web. Le point de terminaison du service que j'utilisais pour les dates désactivées était configuré dans Web.Config, mais pas dans Web.Dev.Config (ou pour d'autres environnements). Une fois que les remplacements de terminaux ont été configurés dans les transformations de configuration, le monde (de développement pour cette application) est devenu un bel endroit. :-) L'erreur 404 renvoyée était techniquement correcte, mais pas très utile. Nous vous remercions de votre aide. – Ahliana

0

Bien que je suis d'accord avec beaucoup de la réponse d'Eli, je ne suis pas d'accord avec son rejet de Url.Action et l'autre URL générant des assistants MVC. Le point à eux est qu'ils sont accrochés dans le moteur de routage de MVC, donc si une route change et que vous utilisez les helpers URL, vous devez faire zéro mise à jour des URL dans vos vues.Mais si vous avez codé en dur toutes les URL au lieu d'utiliser Url.Action, vous devrez revenir en arrière et modifier manuellement chaque URL.

Voici un excellent article de Phil Haack avec un exemple de la façon dont Url.Action a sauvé beaucoup de maux de tête lorsque vous travaillez autour d'un bogue dans MVC: http://haacked.com/archive/2011/02/20/routing-regression-with-two-consecutive-optional-url-parameters.aspx