SL 4 и Служба данных WCF: исключение InvalidOperationException - > исключение SecurityException
Вы подумаете: "эта проблема решалась много-много раз. Так почему же он не пользуется Google?- Пожалуйста, поверь мне, я перепробовал все. Я занимаюсь этой проблемой с прошлой недели. Я читал много блогов и искал MSDN. Но я ничего не понимаю.
Так вот в чем проблема. Существует одно приложение Silverlight 4 и Служба данных WCF, оба работают наlocalhost
.
Это и есть код. Думаю, ничего особенного.
private void InitializeData()
{
var query = (from item in ObjCtx.TestTgt
select item) as DataServiceQuery<TestTgt>;
Debug.Assert(query != null, "'query' is null");
query.BeginExecute(OnLoadDataFinished, query);
}
private void OnLoadDataFinished(IAsyncResult ar)
{
try
{
var query = ar.AsyncState as DataServiceQuery<TestTgt>;
Debug.Assert(query != null, "'query' is null");
var res = query.EndExecute(ar).ToList();
Data.Data = new ObservableCollection<TestTgt>(res);
}
catch(Exception ex)
{
Data.StateDescription = String.Format("Exception occured.{0}{0}{1}", Environment.NewLine, AgExMsgFormatter.GetExText(ex));
}
}
В OnLoadData
в этой строке: var res = query.EndExecute(ar).ToList();
Следующее исключение происходит.
Произошло исключение.
[исключение]
[Тип:] 'InvalidOperationException'
[Сообщение:] ' при обработке этого запроса произошла ошибка.'
[CALLSTACK:]
в системе.Данные.Сервисы.Клиент.BaseAsyncResult.EndExecute[T](источник объекта, строковый метод, iasyncresult asyncResult)
в системе.Данные.Сервисы.Клиент.Queryresult с.EndExecute [TElement](источник объекта, IAsyncResult asyncResult)
около Система.Данные.Сервисы.Клиент.DataServiceRequest.EndExecute [TElement] (источник объекта, контекст DataServiceContext, IAsyncResult asyncResult)
в системе.Данные.Сервисы.Клиент.DataServiceQuery`1.EndExecute (IAsyncResult asyncResult)
в SimpleGrid.SimpleGridVm.OnLoadDataFinished(IAsyncResult ar)[INNEREXCEPTION]
[Тип:] 'SecurityException'
[Сообщение:] "
[CALLSTACK:]
около Системы.Чистая.Браузера.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, состояние объекта)
в системе.Чистая.Браузера.ClientHttpWebRequest.Метода endgetresponse(объекта iasyncresult asyncresult, к)
в системе.Данные.Сервисы.Http.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
в системе.Данные.Сервисы.Клиент.Queryresult с.AsyncEndGetResponse(IAsyncResult asyncResult)[INNEREXCEPTION]
[Тип:] 'SecurityException'
[СООБЩЕНИЕ:] - Ошибка системы безопасности.'
[CALLSTACK:]
в системе.Чистая.Браузера.ClientHttpWebRequest.InternalEndGetResponse(объекта iasyncresult asyncresult, к)
в системе.Чистая.Браузера.ClientHttpWebRequest.с__DisplayClass5.Б__4(Объект sendState)
в системе.Чистая.Браузера.AsyncHelper.с__DisplayClass2.б__0(объект sendState)
[/INNEREXCEPTION]
[/INNEREXCEPTION]
[/Исключение]
В качестве режима аутентификации я хочу использовать Windows
. Оба настроены для этого в IIS. Веб-служба запущена и доставляет правильные данные.
Так что же я упускаю? Я подумал, что это должно сработать. Любая помощь будет оценена по достоинству.
С уважением
4 ответа:
Ваша проблема выглядит как междоменная ошибка: приложение silverlight по умолчанию не может выполнять междоменные вызовы веб-служб. Это означает, что если ваше приложение cassini hosted SL (например, domain localhost:4314) попытается получить доступ к службе WCF в домене localhost, вызов завершится ошибкой с исключением безопасности.
Вы можете легко поймать проблему с помощью fiddler или сетевой вкладки firebug (в firefox): приложение сначала пытается получить доступ к файлу с именем " clientaccesspolicy.xml " ВКЛ корень домена webservice. Этот файл определяет политику на сервере WCF, которая разрешает междоменные вызовы на сервере.
Вот пример файла политики crossdomain, который позволяет любому SL-приложению получить доступ к любым веб-сервисам в этом домене:
<?xml version="1.0" encoding="utf-8"?> <access-policy> <cross-domain-access> <policy> <allow-from http-request-headers="SOAPAction"> <domain uri="*"/> </allow-from> <grant-to> <resource path="/" include-subpaths="true"/> </grant-to> </policy> <policy > <allow-from http-methods="*"> <domain uri="*"/> </allow-from> <grant-to> <resource path="/" include-subpaths="true"/> </grant-to> </policy> </cross-domain-access> </access-policy>
Однако вы можете быть немного более конкретным. Дополнительная информация доступна на MSDN :
Хм, ладно, это удивительно, но я понял. Проблема не в аутентификации или чем-то подобном. Это отладчик. Веб-служба не размещается на веб-узле приложения Silverlight. Таким образом, вызовы веб-службы терпят неудачу.
При загрузке развернутого сайта в браузере все работает абсолютно нормально. Для меня это выглядит несколько странно, но, возможно, кто-то сможет дать мне хорошее объяснение такого поведения.
Но это поднимает еще одну проблему. Как мне это сделать отладка приложения Silverlight, когда оно ссылается на внешнюю веб-службу. Возможно, я открою для этого отдельную нить.
С уважением
Вот мое решение:
- служба RIA работает, как вы и сказали, на localhost.
- ошибка возникает, когда проект Silverlight является проектом statup.
- служба RIA вызывается в этом случае в контексте другого web-страница.
- Visual Studio Debugger предупреждает об этом, но всплывающее окно часто проверено на "не показывать".
Решение таково:
- задайте веб-проект в решении в качестве стартового проекта.
- Установите генерируется, тестовая страница.html как начальная страница.
И служба RIA работает.