(Многопользовательские службы WCF) Методы без параметров с маршрутизацией URL для WCF - PullRequest
2 голосов
/ 26 июля 2011

Это связанный с моим предыдущим вопросом вопрос, но другой.

После многих поисков я не могу найти лучшее решение для следующей проблемы WCF.

Существует только один файл SVC, но несколько URL-адресов для доступа к нему, например. У организации Org1 будет URL http://CRMserver_name/Org1/XRMServices/2011/Organization.svc, а у Org2 будет http://CRMserver_name/Org2/XRMServices/2011/Organization.svc

Я пытался сделать это с помощью маршрутизации URL, но проблема в том, что он создает службы REST, которые нам не нужны Мы должны иметь возможность доступа к этим сервисам, как к обычному сервису WCF. Так что, если мы добавим URL http://CRMserver_name/Org1/XRMServices/2011/Organization.svc в тестовый клиент WCF, он должен работать.

CRM делает это, так что есть способ, но я не могу его найти. Помоги мне!

Спасибо, Nilesh

Ответы [ 3 ]

1 голос
/ 26 июля 2011

Я не уверен, решит ли это вашу проблему, но посмотрите на модуль IIS Url Rewrite.Это может решить вашу проблему.

0 голосов
/ 20 декабря 2012

Я нашел то, что я считаю лучшим подходом. Вместо того, чтобы пытаться выбрать целевой Uri из объекта IncomingMessageHeaders (который дает вам представление сервера для хоста, а не для клиента), вместо этого выберите его из заголовков HttpRequest.

Вот пара сервисных методов, которые я создал, которые доказывают это двумя способами:

  1. GetTenantByRewrittenURL работает в сочетании с правилом перезаписи URL 2.0. Это правило находит имя арендатора в первой части пути Uri (после домена), например, www.mydomain.com / tenant1 / MyService.svc . Затем (а) перезаписывает URL-адрес, удаляя идентификатор арендатора, и (б) сохраняет идентификатор арендатора в поле заголовка HTTP_REFERER. Я могу дать вам правило перезаписи URL, чтобы сделать это, если вы не уверены; не забудьте также добавить HTTP_REFERER в список допустимых серверных переменных в конфигурации перезаписи URL.

  2. GetTenantByFakeHost работает в сочетании с заголовками узлов. Для этого я добавил заголовок узла в свои привязки IIS для ожидания запросов в форме tenant1 .mydomain.com / MyService.svc

Похоже, это позволяет достичь того, к чему вы стремились, и, надеюсь, вы сможете получить доступ к заголовкам Http через ваш средний уровень через OperationContext, хотя я еще не проверял это.

   public string GetTenantIDByRewrittenURL()
    {
        HttpRequestMessageProperty prop = (HttpRequestMessageProperty) OperationContext.Current.IncomingMessageProperties[HttpRequestMessageProperty.Name];
        string tenantID = prop.Headers[HttpRequestHeader.Referer];

        return tenantID;
    }

    public string GetTenantIDByFakeHost()
    {
        HttpRequestMessageProperty prop = (HttpRequestMessageProperty)OperationContext.Current.IncomingMessageProperties[HttpRequestMessageProperty.Name];
        string tenantID = prop.Headers[HttpRequestHeader.Host];

        return tenantID;
    }
0 голосов
/ 05 августа 2011

После долгих исследований я иду безопасным путем для достижения этой цели.Я собираюсь создать отдельные проекты WCF для каждого арендатора и разместить их в отдельных виртуальных каталогах IIS.например, для Tenant1 - http://localhost/ Tenant1/Service1.svc и для Tenant2 - http://localhost/Tenant2/Service1.svc Обратите внимание, что имя SVC одинаково.Затем я удаляю IService1.cs и Service1.svc.cs из Tenant2 и добавляю существующий файл как ссылку из Tenant1.Я должен сделать это для каждого нового арендатора, и поэтому это не чистое решение.Теперь мой обозреватель решений выглядит следующим образом.

SoluExp

Здесь WcfService3 предназначен для Tenant1, а WcfService1 - для Tenant2 (извините за эти запутанные имена. Я могу исправить это, если кому-то понадобится).Поэтому мои свойства WcfService3 выглядят следующим образом.

Project Prop

Теперь и для сервисного кода http://localhost/ Tenant1/Service1.svc, и для http://localhost/ Tenant2/Service1.svc в одном месте, которое находится в WcfServices3-> Service1.svc.cs,Следующий код создаст объект соединения с базой данных для конкретного вызова метода.

    private static string dbServerName = "YourDBServerName";    
    private static SqlConnection dbConnection = createDBConnection();            
    private static SqlConnection createDBConnection()
    {
        Uri fullUri = OperationContext.Current.IncomingMessageHeaders.To;
        Uri baseAddress = new Uri(@"http://localhost");
        UriTemplate template = new UriTemplate(@"/{orgName}/Service1.svc");

        // retrieve the value of the artist segment
        UriTemplateMatch match = template.Match(baseAddress, fullUri);
        String orgName = match.BoundVariables["orgName"];        

        SqlConnection objConnection = new SqlConnection();
        objConnection.ConnectionString = createConnString(orgName);

        return objConnection;
    }

    private static string createConnString(string orgName)
    {
        return (String.Format("Data Source={0};Initial Catalog={1}_MSCRM;User Id=UserId1;Password=PasswordForUserId1;", dbServerName, orgName));
    }

Я знаю, что это не реальное решение проблемы (многопользовательские службы WCF), а быстрая, простая и безопасная работа.Надеюсь, это кому-нибудь поможет.Также, если вы видите какие-либо проблемы здесь или знаете лучшее решение, пожалуйста, дайте мне знать.

-Nilesh

...