2013-03-05 76 views
4

我試圖通過SSIS獲取BingAds數據在我們的會計系統來存儲。我已經添加了服務參考https://api.sandbox.bingads.microsoft.com/Api/Advertiser/v8/CampaignManagement/CampaignManagementService.svc?wsdl進行測試。SSIS隨着腳本組件和服務引用

我從http://msdn.microsoft.com/en-us/library/adcenter-campaign-management-csharp-samples-get-campaigns.aspx直接複製的GetCampaigns代碼,並略作修改,因爲這不是一個控制檯應用程序。

當我運行我的腳本組件,我得到以下信息:

Message 
Could not find default endpoint element that references contract 
'BingAds.CampaignManagementService.ICampaignManagementService' in the ServiceModel 
client configuration section. This might be because no configuration file was 
found for your application, or because no endpoint element matching this contract 
could be found in the client element. 

我的app.config看起來應該具有的選擇所需要的一切。我錯過了什麼嗎?

我的app.config低於:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.serviceModel> 
     <bindings> 
      <basicHttpBinding> 
       <binding name="BasicHttpBinding_ICampaignManagementService" closeTimeout="00:01:00" 
        openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
        allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" 
        maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" 
        messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" 
        useDefaultWebProxy="true"> 
        <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 
         maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
        <security mode="Transport"> 
         <transport clientCredentialType="None" proxyCredentialType="None" 
          realm="" /> 
         <message clientCredentialType="UserName" algorithmSuite="Default" /> 
        </security> 
       </binding> 
      </basicHttpBinding> 
     </bindings> 
     <client> 
      <endpoint address="https://api.sandbox.bingads.microsoft.com/Api/Advertiser/V8/CampaignManagement/CampaignManagementService.svc" 
       binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ICampaignManagementService" 
       contract="BingAds.CampaignManagementService.ICampaignManagementService" 
       name="BasicHttpBinding_ICampaignManagementService" /> 
     </client> 
    </system.serviceModel> 
</configuration> 

而且我的腳本組件代碼如下:

#region Namespaces 
using System; 
using System.Data; 
using Microsoft.SqlServer.Dts.Pipeline.Wrapper; 
using Microsoft.SqlServer.Dts.Runtime.Wrapper; 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.ServiceModel; 
using System.IO; 
using System.Xml; 
using System.Net; 

// @TODO this should be something more sane; we'll get to that 
using SC_356d75396bc04171b425bdd1a48dd7b6.BingAds.CampaignManagementService; 
#endregion 

namespace GetCampaignsByAccount 
{ 

    [Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute] 
    public class ScriptMain : UserComponent 
    { 
     private static CampaignManagementServiceClient service = null; 

     // private static StringBuilder output_messages = new StringBuilder(); 
     private static List<string> strings = new List<string>(); 

     // Specify your credentials. 
     private static string m_password = ""; 
     private static string m_username = ""; 
     private static string m_token = ""; 

     // Specify the advertiser's account ID and customer ID. 
     private static long m_accountId = null; 
     private static long m_customerId = null; 

     // Simple example that shows how to create a campaign. 
     static void Main() 
     { 
      Campaign[] campaigns = null; 

      try 
      { 
       CampaignManagementServiceClient service = new CampaignManagementServiceClient(); 

       campaigns = GetCampaigns(m_customerId, m_accountId); 

       // Print information about the campaigns. 
       if (campaigns.Length > 0) { 
        AddMessage("Account {0} contains the following campaigns", m_accountId); 

        foreach (Campaign campaign in campaigns) { 
         AddMessage("Campaign: {0}", campaign.Name); 
         AddMessage("ID: {0}", campaign.Id); 
         // AddMessage("Status: {0}", campaign.Status); 
         AddMessage("Time zone: {0}", campaign.TimeZone); 
         // AddMessage("Budget type: {0}", campaign.BudgetType); 

         if (BudgetLimitType.MonthlyBudgetSpendUntilDepleted == campaign.BudgetType) 
         { 
          Console.WriteLine("Monthly budget: {0:C}", campaign.MonthlyBudget); 
         } 
         else 
         { 
          Console.WriteLine("Daily budget: {0:C}", campaign.DailyBudget); 
         } 

         Console.WriteLine(); 
        } 
       } 
       else 
       { 
        AddMessage("Account {0} does not contain campaigns.", m_accountId); 
       } 
       service.Close(); 
      } 
      catch (CommunicationException e) 
      { 
       AddMessage("{0}", "Communication Exception!"); 
       AddMessage("{0}", e.Message); 
       AddMessage("{0}", e.StackTrace); 

       if (null != e.InnerException) 
       { 
        AddMessage("{0}", "Inner Exception!"); 
        AddMessage("{0}", e.InnerException.Message); 
        AddMessage("{0}", e.InnerException.StackTrace); 
       } 

       if (service != null) 
       { 
        service.Abort(); 
       } 
      } 
      catch (TimeoutException e) 
      { 
       AddMessage("{0}", "Timeout Exception!"); 
       AddMessage("{0}", e.Message); 
       AddMessage("{0}", e.StackTrace); 

       if (service != null) 
       { 
        service.Abort(); 
       } 
      } 
      catch (Exception e) 
      { 
       // Ignore fault exceptions that we already caught. 

       if (e.InnerException is FaultException) 
       { 
        ; 
       } 
       else 
       { 
        AddMessage("{0}", "Other Exception!"); 
        AddMessage("{0}", e.Message); 
        AddMessage("{0}", e.StackTrace); 
       } 


       if (service != null) 
       { 
        service.Abort(); 
       } 
      } 
     } 

     private static void AddMessage(string format, string str) 
     { 
      string[] lines = str.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); 
      foreach (string value in lines) 
      { 
       string longVal = String.Format(format, value); 
       strings.Add(longVal.Substring(0, Math.Min(longVal.Length, 8000))); 
      } 
     } 

     private static void AddMessage(string format, long str) 
     { 
      strings.Add(String.Format(format, str)); 
     } 

     private static void AddMessage(string format, long? str) 
     { 
      strings.Add(String.Format(format, str)); 
     } 

     static Campaign[] GetCampaigns(long customerId, long accountId) 
     { 
      GetCampaignsByAccountIdRequest request = new GetCampaignsByAccountIdRequest(); 
      GetCampaignsByAccountIdResponse response = null; 

      // Set the header information. 
      request.CustomerId = customerId.ToString(); 
      request.CustomerAccountId = accountId.ToString(); 
      request.DeveloperToken = m_token; 
      request.UserName = m_username; 
      request.Password = m_password; 

      // Set the request information. 
      request.AccountId = accountId; 

      try 
      { 
       response = service.GetCampaignsByAccountId(request); 
      } 
      catch (FaultException<AdApiFaultDetail> fault) 
      { 
       // Log this fault. 
       strings.Add("GetCampaignsByAccountId failed with the following faults:\n"); 

       foreach (AdApiError error in fault.Detail.Errors) 
       { 
        if (105 == error.Code) 
        { // InvalidCredentials 
         Console.WriteLine("The specified credentials are not valid " + 
          "or the account is inactive."); 
        } 
        else 
        { 
         Console.WriteLine("Error code: {0} ({1})\nMessage: {2}\nDetail: {3}\n", 
          error.ErrorCode, error.Code, error.Message, error.Detail); 
        } 
       } 

       throw new Exception("", fault); 
      } 
      catch (FaultException<ApiFaultDetail> fault) 
      { 
       // Log this fault. 
       Console.WriteLine("GetCampaignsByAccountId failed with the following faults:\n"); 

       foreach (OperationError error in fault.Detail.OperationErrors) 
       { 
        switch (error.Code) 
        { 
         case 106: // UserIsNotAuthorized 
          Console.WriteLine("The user is not authorized to call this operation."); 
          break; 

         case 1030: // CampaignServiceAccountIdHasToBeSpecified 
          Console.WriteLine("The CustomerAccountId header element " + 
           "cannot be null or empty."); 
          break; 

         case 1102: // CampaignServiceInvalidAccountId 
          Console.WriteLine("The account ID is not valid"); 
          break; 

         default: 
          Console.WriteLine("Error code: {0} ({1})\nMessage: {2}\nDetail: {3}\n", 
           error.ErrorCode, error.Code, error.Message, error.Details); 
          break; 
        } 
       } 

       // This is not a batch operation, so there should be no batch errors. 
       foreach (BatchError error in fault.Detail.BatchErrors) 
       { 
        Console.WriteLine("Unable to add extension #{0}", error.Index); 
        Console.WriteLine("Error code: {0} ({1})\nMessage: {2}\nDetail: {3}\n", 
         error.ErrorCode, error.Code, error.Message, error.Details); 
       } 

       throw new Exception("", fault); 
      } 

      return response.Campaigns; 
     } 

     /// <summary> 
     /// This method is called once, before rows begin to be processed in the data flow. 
     /// 
     /// You can remove this method if you don't need to do anything here. 
     /// </summary> 
     public override void PreExecute() 
     { 
      base.PreExecute(); 
     } 

     /// <summary> 
     /// This method is called after all the rows have passed through this component. 
     /// 
     /// You can delete this method if you don't need to do anything here. 
     /// </summary> 
     public override void PostExecute() 
     { 
      base.PostExecute(); 
     } 

     public override void CreateNewOutputRows() 
     { 

      Main(); 

      foreach (string value in strings) 
      { 
       MessagesBuffer.AddRow(); 
       MessagesBuffer.Message = value; 
      } 

     } 
    } 
} 
+0

如果你把你提供的代碼,將其添加到一個.NET控制檯應用程序,它的工作?你需要註釋掉對'MessagesBuffer'的引用,否則,我的心理解析說它應該是好的。也許刪除超類和覆蓋。無論如何,這是我的隔離無論是「惡意代碼」或「怪異SSIS」 – billinkc 2013-03-05 14:59:46

+0

格倫通常的做法,你有沒有得到這個工作?如果是這樣,你可以發佈工作代碼,例如使用?謝謝 – 007 2016-02-26 18:43:41

+0

您在BingAds服務引用中定義的CampaignManagementServiceClient()方法是否有多個構造函數,允許您重載它。在我的情況下,我從工作控制檯應用程序複製和粘貼服務生成的命名空間到我的SSIS組件腳本。我的方法調用從ServiceSoapClient服務=新的ServiceSoapClient()到ServiceSoapClient服務=新的ServiceSoapClient(綁定,remoteAddress)。 binding和remoteAddress參數是在添加服務引用時在控制檯應用程序中創建的app.config文件中定義的對象。 – Lew 2017-09-06 20:41:59

回答

3

的配置文件.NET看起來在加載配置數據是一個實際運行的可執行文件;添加一個app.config到你的SSIS腳本組件的項目不會產生一個SSIS知道要查找的配置文件。根據您選擇運行軟件包的方式,它將查找BIDS或SQL Server或dtexec的配置文件。

你會好得多構建您的終端代碼和完全繞過配置文件。如果大多數配置選項都是默認值,那麼它並不那麼複雜,因爲您只需設置更改的屬性即可。

這個堆棧溢出問題應該告訴你如何做到這一點:

WCF Configuration without a config file

+0

良好的漁獲物,它甚至沒有註冊該配置文件參與 – billinkc 2013-03-05 15:08:02

+0

我沒有雖然創建'app.config'。 Visual Studio沒有。我會嘗試使用WCF配置選項。 – 2013-03-05 15:41:36

+1

每次添加服務引用時,VS都會創建一個app.config;它沒有注意到有問題的項目類型不能使用app.config的事實。 – 2013-03-05 16:04:45

0

對於使用SSDT 2015年的,爲.config文件的文件位置使用調試器時,已轉移;他們現在可以在以下路徑下找到:C:\ Program Files文件(x86)的\微軟的Visual Studio 14.0 \ Common7 \ IDE \擴展\微軟\ SSIS \ 140 \ BINN