Więc mam proste Signalr projektu/Knockout, który używa wtyczki mapowania do wiązania prosty obiekt (przedmiot z tablicą więcej elementów) do ViewModels I zdefiniowanego w JS:Sygnalizator deserializuje moje obiekty niepoprawnie w IIS 7.5 i Edge/IE, foreverFrame jest zepsuty?
var someObjectMapping = {
'MyItemArray': {
create: function (options) {
return new MyItemViewModel(options.data);
}
}
}
var myItemMapping = {
'ItemChildren': {
create: function (options) {
return new ItemChildViewModel(options.data);
}
}
}
var SomeObjectViewModel = function (data) {
ko.mapping.fromJS(data, someObjectMapping, this);
}
var MyItemViewModel = function (data) {
ko.mapping.fromJS(data, myItemMapping, this);
}
var ItemChildViewModel = function (data) {
ko.mapping.fromJS(data, null, this);
}
używam ustawień domyślnych SignalR do połącz się z moim hubem tak:
var myHubProxy = $.connection.myHub;
myHubProxy.client.processSomeObject = function(someObject) {
console.log('SomeObject received');
var viewModel = new SomeObjectViewModel(someObject);
ko.applyBindings(viewModel);
}
$.connection.hub.start().done(function() {
console.log('Now connected, connection ID=' + $.connection.hub.id);
myHubProxy.server.getSomeObject();
});
Kiedy mój obiekt wraca, nokaut wykonuje wiązanie i mapowanie zostaje przetworzone. Następnie obiekt i jego tablice podrzędne są naturalnie wydanego na stronie:
<h2 data-bind="text: MyItem"></h2>
<ul data-bind="foreach: MyItemArray">
<li>
<span data-bind="text: Name"></span>
<ul data-bind="foreach: ItemChildren">
<li data-bind="text: Name"></li>
</ul>
</li>
</ul>
Teraz dla kicker: To działa na moim komputerze lokalnym (Win 10, IIS Express), we wszystkich przeglądarkach (Chrome/Firefox/Safari/IE), nie ma problemu. Kiedy jednak opublikuję to w IIS 7.5, działa on we wszystkich przeglądarkach oprócz Internet Explorera 8-10 i Microsoft Edge. Ten sam kod.
Kiedy przewiercić F12 zauważam, że z IIS, funkcja tworzenia w pierwszym mapowaniem dostaje tablicę:
Kiedy zamiast, na pierwszej przerwie, byłbym pierwszą pozycję moja tablica jak to robi na moim komputerze lokalnym:
wiercenia callstack ujawnia, że rodzic obiekt w kN Funkcja createCallback ockout.mapping nie jest interpretowany jako tablicę, jak powinien:
Jednak na moim komputerze lokalnym, to działa zgodnie z oczekiwaniami:
dziwo, jeden z dwie rzeczy mogą obejść ten problem: Po pierwsze, jeśli serializuje się obiekt, wracam z SignalR, a następnie go dealizuję przed powiązaniem z moim modelem nokautu, wszystko działa we wszystkich przeglądarkach od IIS 7.5:
Może to jednak wpłynąć na wydajność.
LUB jeśli wymusić transportu SignalR do longPolling, znowu wszystko działa we wszystkich przeglądarkach z IIS 7.5:
$.connection.hub.start({ transport: "longPolling" }).done(function() {
console.log('Now connected, connection ID=' + $.connection.hub.id);
myHubProxy.server.getSomeObject();
});
Ale wtedy nie miałby zalety WebSockets dostarcza ponad odpytywania.
IIS 7.5 nie obsługuje WebSockets
Mogę też zakodować moje json i powiązać go z nokaut, który działa zgodnie z oczekiwaniami we wszystkich przeglądarkach.
Zajęło mi to na zawsze odkrycie, co się dzieje, a ja walczyłem, aby wymyślić to. Dziwne, że działa to z IIS 7.5 we wszystkich innych przeglądarkach, ale w IE/Edge, gdy mają ten sam prosty skrypt.Działa również we wszystkich przeglądarkach IIS 10 (nie-Express), co nie jest opcją dla serwera, na który publikuję.
Edytuj: Uffe zwrócił uwagę, że IIS 7.5 nie obsługuje WebSockets. Po włączeniu rejestrowania zobaczyłem, że dla IIS 7.5, Signalr zamiast tego będzie zastępował ForeverFrame dla IE i serverSentEvents (which isn't supported in IE) dla innych przeglądarek.
ja również testowane zmuszając foreverFrame, który odtworzył problem na moim komputerze z IIS 10 Express:
$.connection.hub.start({ transport: 'foreverFrame'}).done(function() {
console.log('Now connected, connection ID=' + $.connection.hub.id);
myHubProxy.server.getSomeObject();
});
Więc kolejny Rozwiązaniem byłoby pominąć foreverFrame z transportu całkowicie podczas publikowania na IIS 7.5 tak:
$.connection.hub.start({ transport: ['serverSentEvents','longPolling']}).done(function() {
console.log('Now connected, connection ID=' + $.connection.hub.id);
myHubProxy.server.getSomeObject();
});
Oto przykładowy projekt, który reprodukuje problem: https://onedrive.live.com/redir?resid=D4E23CA0ED671323!1466815&authkey=!AEAEBajrZx3y8e4&ithint=folder%2csln
To nie pomaga. Nie zdawałem sobie sprawy, że IIS 7.5 nie obsługuje webSockets. Mogę odtworzyć problem w dowolnej wersji IIS przez wymuszenie foreverFrame. Zaktualizowałem wpis, aby odzwierciedlić problem. Dzięki. – Jarem
Nie wydaje się, aby dotyczyło to problemu SignalR zachowując się inaczej na lokalnym hosta vs serwer zdalny, jak podano w żądaniu. Wygląda na to, że SignalR + knockout.mapping nie działa w IE (Chrome i Firefox działają), chyba że użyto długiego pollingu, z wyjątkiem lokalnego hosta. –
Nigdy nie używam SignalR, chciałem tylko pomóc facetowi, ponieważ wydawało mu się, że może uzyskać websockets z signalr poniżej IIS8 ... – Uffe