1

我在 stackoverflow 上搜索了很多已经发布的答案,但到目前为止,没有一个解决方案没有解决我的问题。那是研究和故障排除的第二天,没有结果,所以我要寻求其他人的帮助。我正在开发一个 WPF 数据库应用程序,我想在 WPF 应用程序和数据库之间添加一个中间层 (WCF)。

WCF 服务有两个服务合同,都启用了自定义用户名/密码身份验证(也需要会话)。第一个服务合同 (IAppUserService) 将服务于将由本地用户运行的 WPF 应用程序,第二个服务合同将服务于客户可访问的网站 (IAppClientService)。

我已经包含了以下源代码:

DCMAppService.svc.cs

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Configuration;
using System.IdentityModel.Selectors;
using MySql.Data.MySqlClient;
using DCMAppService.classes;

namespace DCMAppService
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
    public class AppClientService : IAppClientService
    {
        public bool Login(string userName, string password)
        {
                    // TODO:
            return true;
        }

        public bool Logout()
        {
                    // TODO:
            return true;
        }
    }

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
    public class AppUserService : IAppUserService
    {
        private User currentUser;


        #region User functions
        public User Login(string userName, string password)
        {
                    // Does Login here...
        }

        public bool Logout()
        {
                    // Does logout here...
        }

        public bool isLoggedIn()
        {
            return (currentUser != null);
        }

        public User AddUser(string firstName, string lastName, string userName, string password, ushort status)
        {
                    // Implements business logic...
        }

        public bool UpdateUser(uint id, string firstName, string lastName, string userName, string password, ushort status)
        {
                    // Implements business logic...
        }

        public bool DeleteUser(uint id)
        {
                    // Implements business logic...
        }

        public List<User> GetUsersList()
        {
                    // Implements business logic...
        }
        #endregion

        #region Client functions
        public Client AddClient(string title, bool allowWebAccess, string userName, string password)
        {
                    // Implements business logic...
        }

        public bool UpdateClient(uint id, string title, bool allowWebAccess, string userName, string password)
        {
                    // Implements business logic...
        }

        public bool DeleteClient(uint id)
        {
                    // Implements business logic...
        }

        public List<Client> GetClientsList()
        {
                    // Implements business logic...
        }
        #endregion
    }

    public class CustomUserNameValidator : UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            if (userName == null || password == null)
                throw new ArgumentNullException();

            // Custom login implementation
                    // TODO:
                    int ret = 1;
            if (ret != 1)
                throw new FaultException("Invalid username or password", new FaultCode("AuthError"));
        }
    }
}

服务的接口文件包含以下内容:

IDCMAppService.cs

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace DCMAppService
{
    [ServiceContract(SessionMode = SessionMode.Required)]
    public interface IAppClientService
    {
        [OperationContract(IsInitiating = true, IsTerminating = false)]
        bool Login(string userName, string password);

        [OperationContract(IsInitiating = false, IsTerminating = true)]
        bool Logout();
    }

    [ServiceContract(SessionMode = SessionMode.Required)]
    public interface IAppUserService
    {
        [OperationContract]
        bool HealthCheck();

        #region User functions
        [OperationContract(IsInitiating = true, IsTerminating = false)]
        User Login(string userName, string password);

        [OperationContract(IsInitiating = false, IsTerminating = true)]
        bool Logout();

        [OperationContract(IsInitiating = false)]
        User AddUser(string firstName, string lastName, string userName, string password, ushort status);

        [OperationContract(IsInitiating = false)]
        bool UpdateUser(uint id, string firstName, string lastName, string userName, string password, ushort status);

        [OperationContract(IsInitiating = false)]
        bool DeleteUser(uint id);

        [OperationContract(IsInitiating = false)]
        List<User> GetUsersList();
        #endregion

        #region Client functions
        [OperationContract(IsInitiating = false)]
        Client AddClient(string title, bool allowWebAccess, string userName, string password);

        [OperationContract(IsInitiating = false)]
        bool UpdateClient(uint id, string title, bool allowWebAccess, string userName, string password);

        [OperationContract(IsInitiating = false)]
        bool DeleteClient(uint id);

        [OperationContract(IsInitiating = false)]
        List<Client> GetClientsList();
        #endregion
    }
}

请注意,它包含WCF 必须服务的两种不同的服务协定(一种用于用户,另一种用于客户端)。

Web.config 文件包含以下内容:

<?xml version="1.0"?>
<configuration>
    <appSettings/>
    <connectionStrings>
        <add name="DCMConnectionString" connectionString="Server=127.0.0.1;Database=xxxxxx;Uid=xxxxxx;Pwd=xxxxxx;" providerName="System.Data.EntityClient"/>
    </connectionStrings>
    <system.web>
        <compilation debug="true" targetFramework="4.0">
        </compilation>
        <!--
        The <authentication> section enables configuration 
        of the security authentication mode used by 
        ASP.NET to identify an incoming user. 
    -->
        <authentication mode="Windows"/>
        <!--
        The <customErrors> section enables configuration 
        of what to do if/when an unhandled error occurs 
        during the execution of a request. Specifically, 
        it enables developers to configure html error pages 
        to be displayed in place of a error stack trace.

        <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
         <error statusCode="403" redirect="NoAccess.htm" />
         <error statusCode="404" redirect="FileNotFound.htm" />
        </customErrors>
      -->
        <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>
    </system.web>
    <system.serviceModel>
        <protocolMapping>
            <remove scheme="http" />
            <add scheme="http" binding="wsHttpBinding" />
        </protocolMapping>
        <bindings>
            <wsHttpBinding>
                <binding name="DCMAppBindingWSConfig" receiveTimeout="03:00:00"
                 sendTimeout="03:00:00">
                    <reliableSession inactivityTimeout="01:00:00" enabled="true" />
                    <security mode="Message">
                        <message clientCredentialType="UserName" />
                    </security>
                </binding>
            </wsHttpBinding>
            <mexHttpBinding>
                <binding name="DCMAppBindingMexConfig" receiveTimeout="00:10:00"
                 sendTimeout="00:10:00" />
            </mexHttpBinding>
        </bindings>
        <services>
            <service behaviorConfiguration="DCMAppService.AppServiceBehavior"
             name="DCMAppService.AppUserService">
                <endpoint address="" binding="wsHttpBinding" name="wsBinding"
                 contract="DCMAppService.IAppUserService">
                    <identity>
                        <dns value="localhost" />
                    </identity>
                </endpoint>
                <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="DCMAppBindingMexConfig"
                 name="mexBinding" contract="IMetadataExchange" />
            </service>
        </services>
        <behaviors>
            <serviceBehaviors>
                <behavior name="DCMAppService.AppServiceBehavior">
                    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="true" />
                    <serviceCredentials>
                        <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="DCMAppService.CustomUserNameValidator, DCMAppService" />
                    </serviceCredentials>
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    </system.serviceModel>
</configuration>

我得到的响应是带有经典消息的错误页面:

此服务的元数据发布当前已禁用。

这很烦人,因为我找不到任何解决方法。

任何帮助将不胜感激。

4

0 回答 0