带有脚本组件和服务引用的 SSIS [英] SSIS With Script Component and Service References

查看:23
本文介绍了带有脚本组件和服务引用的 SSIS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过 SSIS 获取 BingAds 数据以存储在我们的会计系统中.我已将服务引用添加到 https:///api.sandbox.bingads.microsoft.com/Api/Advertiser/v8/CampaignManagement/CampaignManagementService.svc?wsdl 用于测试.

I'm trying to fetch BingAds data via SSIS to store in our accounting system. I've added a Service Reference to https://api.sandbox.bingads.microsoft.com/Api/Advertiser/v8/CampaignManagement/CampaignManagementService.svc?wsdl for testing.

我直接从 http://msdn.microsoft.com/en-us/library/adcenter-campaign-management-csharp-samples-get-campaigns.aspx,并稍作修改,因为这不是一个控制台应用程序.

I've copied the GetCampaigns code directly from http://msdn.microsoft.com/en-us/library/adcenter-campaign-management-csharp-samples-get-campaigns.aspx, and modified slightly, since this isn't a console application.

当我运行我的脚本组件时,我收到以下消息:

When I run my Script Component, I get the following message:

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 看起来应该拥有所需的一切.我错过了什么吗?

My app.config looks like it should have everything that's needed. Am I missing something?

我的 app.config 如下:

My app.config is below:

<?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>

我的脚本组件代码如下:

And my script component code is below:

#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:
");

                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})
Message: {2}
Detail: {3}
",
                            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:
");

                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})
Message: {2}
Detail: {3}
",
                                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})
Message: {2}
Detail: {3}
",
                        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;
            }

        }
    }
}

推荐答案

.NET 在加载配置数据时查找的配置文件是实际运行的可执行文件的配置文件;将 app.config 添加到 SSIS 脚本组件的项目不会生成 SSIS 知道要查找的配置文件.根据您选择运行包的方式,它将寻找 BIDS、SQL Server 或 dtexec 的配置文件.

The configuration file that .NET looks for when it loads configuration data is the one for the executable that's actually running; adding an app.config to your SSIS Script Component's project isn't going to produce a configuration file that SSIS knows to look for. Depending on how you opt to run your packages, it's going to be looking for the configuration file for BIDS, or SQL Server, or dtexec.

最好在代码中构建端点并完全绕过配置文件.如果您的大多数配置选项都是默认值,那么它甚至没有那么复杂,因为您只需要设置更改的属性.

You will be much better off constructing your endpoints in code and bypassing the configuration file entirely. If most of your configuration options are defaults it's not even that complex, as you only need to set the properties that changed.

这个堆栈溢出问题应该告诉你怎么做:

This Stack Overflow Question should show you how to do it:

没有配置文件的 WCF 配置

这篇关于带有脚本组件和服务引用的 SSIS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆