Ошибка SOAP при подключении к веб-службам NetSuite: "Префикс пространства имен" soapenv "не определен"
При подключении к производственной учетной записи NetSuite через API Suitetalk я получаю следующую ошибку:
У меня нет проблем с подключением к учетной записи Sandbox для этого клиента. Я подключаюсь через C# WCF проект. Я не верю, что проблема в проекте C#, так как этот код используется в Production со многими другими клиентами.
Мне кажется, что возвращаемое сообщение SOAP неправильно отформатировано - кажется, что перед элементом soapenv в сообщении SOAP произошел разрыв строки. Я получаю эту ошибку при создании запроса "get" к API(используя паспортный вход). Эта ошибка возникает при любом вызове API, хотя я попытался просто войти через API.
Я дважды проверил данные для входа в систему и информацию об учетной записи для этого клиента, и все кажется в заказах. Кроме того, если эта информация неверна, я должен получать ошибки аутентификации - не искаженные сообщения SOAP.
Любая помощь будет оценена, спасибо!
2 ответа
Оказывается, мне нужно было использовать WSDL webservices.na3.netsuite. У меня сложилось впечатление, что обычный WSDL "webservices.netsuite" будет направлять любые запросы на правильный сервер.
Поэтому при подключении к учетной записи NetSuite через SuiteTalk обязательно используйте правильный WSDL и укажите правильную конечную точку вместе с вашими учетными данными для входа. Вы можете проверить, на каком сервере находится ваша учетная запись, просмотрев URL-адрес при входе в свою учетную запись NetSuite.
Обновить
Я использовал новейший класс DataCenterAwareNetSuiteService для динамического получения правильного центра обработки данных для текущей учетной записи, к которой я пытаюсь подключиться:
class DataCenterAwareNetSuiteService : NetSuiteService
{
private System.Uri OriginalUri;
public DataCenterAwareNetSuiteService(string account, bool doNotSetUrl)
: base()
{
OriginalUri = new System.Uri(this.Url);
if (account == null || account.Length == 0)
account = "empty";
if (!doNotSetUrl)
{
//var temp = getDataCenterUrls(account);
DataCenterUrls urls = getDataCenterUrls(account).dataCenterUrls;
Uri dataCenterUri = new Uri(urls.webservicesDomain + OriginalUri.PathAndQuery);
this.Url = dataCenterUri.ToString();
}
}
public void SetAccount(string account)
{
if (account == null || account.Length == 0)
account = "empty";
this.Url = OriginalUri.AbsoluteUri;
DataCenterUrls urls = getDataCenterUrls(account).dataCenterUrls;
Uri dataCenterUri = new Uri(urls.webservicesDomain + OriginalUri.PathAndQuery);
this.Url = dataCenterUri.ToString();
}
}
Вышеуказанное называется так:
new DataCenterAwareNetSuiteService("*account number*", false);
В последней версии NetSuite были внесены некоторые изменения в URL. Например, теперь вы можете иметь более одного URL-адреса SandBox. Из-за этого формат URL изменился. Номер учетной записи, используемый при аутентификации, теперь также отличается. Для песочниц идентификатор учетной записи теперь передается как ACCOUNTNUMBER_SANDBOXID, например 12345678_SB1.
Вы можете определить URL-адреса для служб SOAP и REST, используя datacenterurls
конечная точка и предоставление учетной записи #, для которой вы хотите определить URL-адреса.
https://rest.netsuite.com/rest/datacenterurls?account=YOUR_ACCOUNT_NUMBER
Функциональность ниже основана на ответе @Charl выше. Ниже я внес пару изменений, которые обеспечивают ту же функциональность без использования наследования. Это может быть более простой реализацией для начинающего программиста, который не знает, как использовать унаследованный класс.
var accountId = "1234567"; // Insert your account ID here
var Service = new NetSuiteService();
Service.Url = new Uri(Service.getDataCenterUrls(accountId).dataCenterUrls.webservicesDomain + new Uri(Service.Url).PathAndQuery).ToString();