自托管WCF没有配置 - 很难理解设置端点

时间:2014-09-12 19:19:53

标签: c# web-services wcf self-hosting

我已经研究了一天了,现在请求专家来征求您的意见。

我有REST服务,这是主要的IIS托管服务。

此服务需要与32位非托管.dll接口。为了做到这一点,我采取了一种常见的方法,即创建一个自托管服务并调用它。

在这样的背景下,我有一点时间让自己主持一个有效的工作。

这是代码:WORKS:

static void Main(string[] args)
        {
            Uri baseAddress = new Uri("http://localhost:8080/theSvc");
            Uri mexUri = new Uri("http://localhost:8080/theSvc/mex");

            // Create the ServiceHost.
            using (ServiceHost host = new ServiceHost(typeof(ImgService), baseAddress))
            {
//                var wsHttpBinding = new WSHttpBinding();
  //              wsHttpBinding.MaxReceivedMessageSize = int.MaxValue;
    //            host.AddServiceEndpoint(typeof(IImgService), wsHttpBinding, baseAddress);

                // Enable metadata publishing.
                ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                smb.HttpGetUrl = mexUri;
                smb.HttpGetEnabled = true;
                smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
                host.Description.Behaviors.Add(smb);



                // Open the ServiceHost to start listening for messages. Since
                // no endpoints are explicitly configured, the runtime will create
                // one endpoint per base address for each service contract implemented
                // by the service.
                host.Open();

                Console.WriteLine("The service is ready at {0}", baseAddress);
                Console.WriteLine("Press <Enter> to stop the service.");
                Console.ReadLine();

                // Close the ServiceHost.
                host.Close();
            }
        }
    }

现在......如果我取消注释这些行以增加maxreceivedMessageSize并从using语句中删除baseAddress,我就不能再添加对该服务的引用:

所以改变这个:

        using (ServiceHost host = new ServiceHost(typeof(ImgService), baseAddress))

对此:

        using (ServiceHost host = new ServiceHost(typeof(ImgService)))

并取消注释:

//                var wsHttpBinding = new WSHttpBinding();
  //              wsHttpBinding.MaxReceivedMessageSize = int.MaxValue;
    //            host.AddServiceEndpoint(typeof(IImgService), wsHttpBinding, baseAddress);

我收到的错误是:

... - &gt;当地主人

There was an error downloading 'http://...:8080/theSvc/_vti_bin/ListData.svc/$metadata'.
The request failed with HTTP status 400: Bad Request.
Metadata contains a reference that cannot be resolved: 'http://...:8080/theSvc'.
Metadata contains a reference that cannot be resolved: 'http://...:8080/theSvc'.
If the service is defined in the current solution, try building the solution and adding the service reference again.

就像在这里张贴的所有人一样......我陷入困境。任何帮助真的很感激。

1 个答案:

答案 0 :(得分:2)

您似乎没有添加服务端点。

这是我用来启动http主机的功能,但是我在Windows服务中托管它。这与您的控制台应用程序相同。但是IIS可能会对它有所不同。

static Uri scannerSvcBaseAddress;
static BasicHttpBinding scannerBinding;
static ServiceHost scannerHost;

public void startScannerWcfService(long eventID)
{
    try
    {
        db.writeServiceLog(eventID, "STARTUP", "=== Scanner WCF Service Starting ===");

        string addressToHostAt = ConfigurationManager.AppSettings["ScannerHostBaseAddress"];

        if (addressToHostAt != null && addressToHostAt.Trim() != string.Empty)
        {

            scannerSvcBaseAddress = new Uri(addressToHostAt);
            scannerHost = new ServiceHost(typeof(BarCodeService.ScannerService), scannerSvcBaseAddress);

            //Allows publishing of METADATA to developers when self hosted on a remote system                 
            ServiceMetadataBehavior smb = scannerHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
            if (smb == null)
            {
                smb = new ServiceMetadataBehavior();
            }
            smb.HttpGetEnabled = true;
            smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
            scannerHost.Description.Behaviors.Add(smb);

            scannerHost.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName, MetadataExchangeBindings.CreateMexHttpBinding(), "mex");

            scannerBinding = new BasicHttpBinding();
            scannerBinding.MaxReceivedMessageSize = 2147483647;
            scannerBinding.Security.Mode = BasicHttpSecurityMode.None;
            scannerBinding.OpenTimeout = new TimeSpan(0, 0, 10);
            scannerBinding.CloseTimeout = new TimeSpan(0, 0, 10);
            scannerBinding.SendTimeout = new TimeSpan(0, 5, 0);
            scannerBinding.ReceiveTimeout = new TimeSpan(0, Global.scanUserIdleLogout * 2, 0);

            //scannerBinding.ReliableSession.InactivityTimeout = new TimeSpan(2, 0, 0, 0);

            scannerHost.AddServiceEndpoint(typeof(BarCodeService.IScannerService), scannerBinding, "");

            var behavior = scannerHost.Description.Behaviors.Find<ServiceDebugBehavior>();
            behavior.IncludeExceptionDetailInFaults = true;


            scannerHost.Open();

            db.writeServiceLog(eventID, "STARTUP", "=== Scanner WCF Service Started ===");
        }
        else
            throw new Exception("Host Base Address not provided");
    }
    catch (Exception ex)
    {
        db.writeServiceLog(eventID, "STARTUP", string.Format("Error in ServiceManager.startScannerWcfService: {0} {1}", ex.Message, ex.StackTrace));
        throw;
    }

}

所有这一切,如上所述,如果您只需要公开一个字符串WCF可能会有点过分。我在Windows服务中使用WCF连接到仓库环境中的手持扫描仪,我对它的执行方式非常满意。虽然最初让它起作用是一件巨大的痛苦。

但是因为在WCF的上下文中提出了这个问题,我认为我会用一个已知的工作函数作出回应,它基本上就是你想要做的。