...

Глобальный модуль (публичный сервис) не отображается после публикации

Тема в разделе "Проблемы/ошибки", создана пользователем Jercy_vz, 15 ноя 2019.

  1. Jercy_vz

    Jercy_vz New Member

    Добрый день!
    Создал глобальный модуль, сохранил, опубликовал. Ошибок не было, но и не отображается мой ГМ в списке публичных сервисов.
    Руководствовался данной статьей https://www.elma-bpm.ru/KB/article-6119.html.
    Подскажите, что может быть не так ? Что я упустил ?
    Код модуля ниже

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.IO;
    using System.Text;
    using System.ServiceModel;
    using System.ServiceModel.Web;
    using System.ServiceModel.Activation;
    using System.Web;
    using EleWise.ELMA;
    using EleWise.ELMA.Model.Services;
    using EleWise.ELMA.ComponentModel;
    using EleWise.ELMA.Model.Attributes;
    using EleWise.ELMA.Model.Managers;
    using EleWise.ELMA.Services.Public;
    using EleWise.ELMA.Security;
    using EleWise.ELMA.Security.Models;
    using EleWise.ELMA.Services;
    using EleWise.ELMA.CRM;
    using EleWise.ELMA.CRM.Models;
    using EleWise.ELMA.Runtime.Managers;
    using EleWise.ELMA.API;
    using EleWise.ELMA.Common;
    using EleWise.ELMA.Security.Models;
    using EleWise.ELMA.CRM.RTCompanyStructure;
    using EleWise.ELMA.ConfigurationModel;
    using EleWise.ELMA.Web.Service;


    namespace PacketELMASend
    {


    [ServiceContract(Namespace = APIRouteProvider.ApiServiceNamespaceRoot)]
    [Description("Сервис для записи пакета")]
    [WsdlDocumentation("Сервис для записи пакета")]
    public interface IRTDynamicsELMAPacketService
    {

    [OperationContract]
    [WebGet(UriTemplate = "/Test?text={testText}")]
    [AuthorizeOperationBehavior]
    [FaultContract(typeof(PublicServiceException))]
    [Description("Удаление объекта IExampleObject")]
    [WsdlDocumentation("Удаление объекта IExampleObject")]
    string Test(string testText);

    }



    /// <summary>
    /// Класс, позволяющий добавить публичный веб сервис уровня модуля
    /// </summary>
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, MaxItemsInObjectGraph = int.MaxValue)]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    [ServiceKnownType("GetEntityKnownTypes", typeof(ServiceKnownTypeHelper))]
    [Component]
    [Uid(GuidS)]
    public class RTDynamicsELMAPacketService : IRTDynamicsELMAPacketService, IPublicAPIWebService
    {
    public const string GuidS = "9038f152-277b-4ed2-a480-fe66f1d5f0ae";

    public string Test (string testText)
    {
    return String.Format("Hello! You have sent this text:{0}",testText);
    }
    }

    }
     
    Последнее редактирование: 15 ноя 2019
  2. pushkarev

    pushkarev Active Member

    Попробовал ваш код на свой версии элма, у меня все получилось, метод появился в API: https://take.ms/YZixq
    Я единственное, что поменял это скопировал юзинги из примера в базе знаний, у вас их как-то очень много и есть видимо какие-то ваши, нестандартные. А так же добавил в проект сборки: System.ServiceModel.Web и EleWise.ELMA.SDK.Web. Ну и Guid свой вставил.
    Код как вы пишите написал в глобальном модуле, все опубликовал, сервер перезагрузил. После этого метод появился в ELMA. И я проверил результат возвращает корректно.
    Проверьте, может вы что-то из этих шагов упустили?
     
    1 это нравится
  3. Jercy_vz

    Jercy_vz New Member

    Спасибо большое за быстрый ответ! Вот чего я не сделал.
    Глупый вопрос, сервер перезагрузить это как ? IIS рестартануть ? Или СУБД тоже ?
     
  4. pushkarev

    pushkarev Active Member

    Имеется ввиду само приложение ELMA. Можно в дизайнере на вкладке Публикация нажать перезагрузить, либо в IIS перезагрузить пул приложения ELMA и сайт. СУБД перезагружать не нужно.
     
  5. Jercy_vz

    Jercy_vz New Member

    Огромное спасибо за помощь! Все получилось!
     
    1 это нравится
  6. Jercy_vz

    Jercy_vz New Member

    Извините, это конечно уже не касается темы этого вопроса. Но может Вы в курсе, как сделать кастомный публичный сервис не требующим авторизацию ?
    Ни в дизайнере ни в инстансе Элмы ничего подобного не нашел. Понимаю что где то оно должно быть, но где ...
     
  7. pushkarev

    pushkarev Active Member

    Я честно говоря не знаю способа, как сделать сервис без авторизации. Подозреваю, что стандартными средствами такой сервис создать нельзя, т.к. код в сценариях в глобальном модуле выполняется в контексте какого-либо пользователя. Могу предложить разработать отдельный сервис (не внутри элмы), который будет работать без авторизации, и который будет уже работать с ELMA, через ее API. Этакий прокси, который будет принимать запросы анонимно, потом авторизовываться в ELMA web API под зашитой в сервис учетной записью и уже под конкретным пользователем выполнять нужные методы. Либо стоит задать вопрос в поддержке, может быть они знают еще другой способ.
     
    1 это нравится
  8. Jercy_vz

    Jercy_vz New Member

    Еще раз, спасибо Вам большое! Я бы наверное не заморачивался с авторизацией, но обнаружил что в другом самописном модуле авторизацию не требует ... Безымянный.png
    По сравнению с моим Безымянный.png
    В любом случае, спасибо Вам, очень помогли!
     
  9. pushkarev

    pushkarev Active Member

    А можете поделиться, как был создан метод без авторизации, в чем там отличия?
     
  10. Jercy_vz

    Jercy_vz New Member

    Вы имеете ввиду код метода ?

    отличий вроде бы в заголовках, атрибутах - не видно.
     
  11. Jercy_vz

    Jercy_vz New Member

    Вот часть кода интерфейса.

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.IO;
    using System.Text;
    using System.ServiceModel;
    using System.ServiceModel.Activation;
    using System.ServiceModel.Web;
    using EleWise.ELMA;
    using EleWise.ELMA.Model.Services;
    using EleWise.ELMA.ComponentModel;
    using EleWise.ELMA.Model.Attributes;
    using EleWise.ELMA.Model.Managers;
    using EleWise.ELMA.Services.Public;
    using EleWise.ELMA.Security;
    using EleWise.ELMA.Security.Models;
    using EleWise.ELMA.Services;
    using EleWise.ELMA.Web.Service;
    using EleWise.ELMA.CRM;
    using EleWise.ELMA.CRM.Models;
    using EleWise.ELMA.Runtime.Managers;
    using EleWise.ELMA.API;
    using EleWise.ELMA.Common;
    using EleWise.ELMA.Security.Managers;
    using EleWise.ELMA.Security.Models;
    using EleWise.ELMA.CRM.RTCompanyStructure;
    using EleWise.ELMA.ConfigurationModel;
    using SynchroDynamicsELMA.Models;
    using RTContractDocumentsScripts;


    namespace SynchroDynamicsELMA.Services
    {


    [ServiceContract(Namespace = APIRouteProvider.ApiServiceNamespaceRoot)]
    [Description("Особый сервис для работы извне")]
    [WsdlDocumentation("Особый сервис для работы извне")]
    public interface IRTDynamicsELMASynchService
    {
    [OperationContract]
    //[WebInvoke(Method="POST")]
    //[AuthorizeOperationBehavior]
    [FaultContract(typeof(PublicServiceException))]
    [Description("Создать новую компанию")]
    [WsdlDocumentation("Создать новую компанию")]
    RTSynchModelReturn CreateCompany(RTSynchModeCompany company);


    А вот сам метод

    public RTSynchModelReturn CreateCompany(RTSynchModeCompany company)
    {
    try
    {

    if (!File.Exists(pathmetodlog))
    {
    File.WriteAllText(pathmetodlog, " \r\n");
    }

    System.IO.File.AppendAllText(pathmetodlog,
    " --- CreateCompany --- /" + DateTime.Now.ToString() + "/ \r\n"+
    "---------------------------------------------------\r\n" +
    " Mcdsoft_name = " + company.Mcdsoft_name + "\r\n"+
    " Mcdsoft_inn = " + company.Mcdsoft_inn +"\r\n" +
    "----------------------------------------------------\r\n", Encoding.GetEncoding("Windows-1251"));

    EleWise.ELMA.CRM.RTCompanyStructure.Models.RTContrCompany newCompany = null;
    var securityService = Locator.GetService<ISecurityService>();

    securityService.RunBySystemUser( () => {

    newCompany = EntityManager<EleWise.ELMA.CRM.RTCompanyStructure.Models.RTContrCompany>.Create();
    newCompany.Name = company.Mcdsoft_name;
    newCompany.INN = company.Mcdsoft_inn;
    newCompany.Save();

    });


    return new RTSynchModelReturn()
    {
    ResultStatus = true,
    IdObject = newCompany.Id,
    MessageError = ""
    };



    } catch (Exception ex)
    {

    return new RTSynchModelReturn() {
    ResultStatus = false,
    IdObject = 0,
    MessageError = "ERROR in method CreateCompany / " + ex.ToString()
    };
    }
    }
     
    1 это нравится
  12. Jercy_vz

    Jercy_vz New Member

    Хм, Вы знаете отличия все же есть. У самого метода (не моего) нет совсем атрибутов. Вот этих

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, MaxItemsInObjectGraph = int.MaxValue)]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    [ServiceKnownType("GetEntityKnownTypes", typeof(ServiceKnownTypeHelper))]
    [Component]
    [Uid(GuidS)]

    Но откровенно говоря я не знаю, могут ли они повлиять

    Update Удалил этот блок, но это ни на что не повлияло
    Update2 Все таки повлияло. Endpoint просто стал недоступен.
     
    Последнее редактирование: 28 ноя 2019
    1 это нравится
  13. Jercy_vz

    Jercy_vz New Member

    Я наконец то понял как сделать метод сервиса не требующим авторизацию.
    Вся суть в этом атрибуте [AuthorizeOperationBehavior]
    После его удаления/комментирования, метод больше не требует авторизации.

    Но там есть и подводные камни, я нашел один из них - после данной манипуляции, при попытке выдернуть из базы Элмы записи по фильтру (например ".Find("Id="+id)"), система вернет пустую коллекцию. Хотя данные заведомо были в базе Элмы.
     
  14. t.ahkyamov

    t.ahkyamov New Member

    По умолчанию, при поиске через менеджер стоят проверки на привилегии. Для обхода требуется можно:
    1. Выставить в фильтре свойство DisableSecurity в true
    2. Запустить поиск от пользователя с привилегиями, вотспользовавшись SecurityService.RunByUser
    3. [Строго не рекомендую!] Запустить поиск с системными привилегиями, воспользовавшись SecurityService.RunWithElevatedPriveleges
     
    1 это нравится

Поделиться: