Я создал веб-службу RESTful (С#, WCF), которая реализует следующий интерфейс:
public interface ITestService
{
[OperationContract]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "?s={aStr}")]
string Test(string aStr);
}
где метод Test()
просто возвращает все, что ему было дано (или по умолчанию "test"
), а также временные метки при вызове метода.
Служба общедоступна, поэтому, когда я вводим URL-адрес в любом браузере:
http://xx.xxx.xxx.xx:41000/TestService/web/
Он возвращает строку "test"
json (или все, что, возможно, было введено с ?s=...
в конце).
Я хочу, чтобы Salesforce отправлял данные на этот веб-сервис.
Мой класс apex выглядит так: он запускается, когда объект добавляется в Salesforce:
public class WebServiceCallout
{
@future (callout=true)
public static void sendNotification(String name)
{
HttpRequest req = new HttpRequest();
HttpResponse res = new HttpResponse();
Http http = new Http();
req.setEndpoint('http://xx.xxx.xxx.xx:41000/TestService/web/');
req.setMethod('POST');
req.setHeader('Content-Type', 'application/json');
req.setBody('');
try
{
res = http.send(req);
}
catch(System.CalloutException e)
{
System.debug('Callout error: '+ e);
System.debug(res.toString());
}
}
}
Когда объект sendNotification()
в Salesforce, в разделе Apex Jobs говорится, что sendNotification()
был завершен. Но служба никогда не поднимала POST этим методом. (Примечание: добавлен IP-адрес службы в настройках удаленного сайта).
Что-то не так с моим синтаксисом?
(На этом этапе я хочу, чтобы Salesforce вызывал веб-сервис - даже не отправляя на него что-либо)
В качестве примера я создал пример Console Application
которое отлично работает с POST для службы.
internal static void Main(string[] args)
{
Uri address = new Uri("http://xx.xxx.xxx.xx:41000/TestService/web/");
// Create the web request
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(address);
// Set type to POST
request.Method = "POST";
request.ContentType = "application/json";
// Create the data we want to send
var postData = "";
// Create a byte array of the data we want to send
var byteData = UTF8Encoding.UTF8.GetBytes(postData);
// Set the content length in the request headers
request.ContentLength = byteData.Length;
// Write data
using (var stream = request.GetRequestStream())
{
stream.Write(byteData, 0, byteData.Length);
}
// Get response
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(
response.GetResponseStream()
).ReadToEnd();
Console.Writeline(responseString);
}
Почему мой класс Apex в выписке Salesforce правильно?
Я понял проблему. Я не указал настройки порта в удаленном месте (что!)
Вышеприведенные примеры кода должны работать безупречно (по крайней мере, для меня)
Подсказки для тех, кто застрял в этом в будущем:
В настройках → Безопасность → Настройки удаленного сайта
Служба (URL удаленного сайта) должна быть в этом формате - где бы вы ее размещали:
http://xx.xxx.xxx.xx:41000
Чтобы проверить приведенный выше код, перейдите по ссылке:
[Ваше имя] → Консоль разработчика → Отладка → Открыть Execute анонимное окно
и скопируйте следующую строку:
WebServiceCallout.sendNotification('Test');
и нажмите " Выполнить".
Код выполняется, и вы должны увидеть журнал выполнения (и любые ошибки с ним).