2

我有一个通过 EntityFramework 与 SQLExpress DB 通信的项目。现在我想在系统中添加一个 WCF 层。

这是我在第一个版本(无 WCF)中的一些代码:

MessageService.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newsletter.DAL;
using System.Data.Entity;
using System.Windows;
using System.Data.Objects.DataClasses;

namespace Newsletter.Services
{
    public class MessageService
    {
        private NewsletterEntities _context;
    public MessageService()
    {
        _context = new NewsletterEntities();
    }
    public Task AddMessageAsync(string subject,string content, bool hasAttachments, DateTime date, Sender sender, MailingList mailingList)
    {
        return Task.Factory.StartNew(() =>
            {
                Message newMessage = new Message();
                newMessage.Subject = subject;
                newMessage.Content = content;
                newMessage.HasAttachments = hasAttachments;
                newMessage.Date = date;
                newMessage.Sender = sender;
                newMessage.MailingList = mailingList;
                _context.Messages.AddObject(newMessage);
                _context.SaveChanges();
            });
    }

    public Task EditMessageAsync(int id, DateTime date, string content, MailingList mailingLists, Sender sender, string subject, bool hasAttachments)
    {
        return Task.Factory.StartNew(() =>
            {
                var messageToChange = (from m in _context.Messages where id == m.MessageID select m).FirstOrDefault();
                if (messageToChange != null)
                {
                    messageToChange.Date = date;
                    messageToChange.Content = content;
                    messageToChange.MailingList = mailingLists;
                    messageToChange.Sender = sender;
                    messageToChange.Subject = subject;
                    messageToChange.HasAttachments = hasAttachments;
                    _context.SaveChanges();
                }
            });
    }

    public Task<List<Message>> GetAllMessagesAsync()
    {
        return Task.Factory.StartNew(() => _context.Messages.ToList());
    }

    public Task<List<MailingList>> GetAllMailingListsAsync()
    {
        return Task.Factory.StartNew(() => _context.MailingLists.ToList());
    }

    public Task<List<Sender>> GetAllSendersAsync()
    {
        return Task.Factory.StartNew(() => _context.Senders.ToList());
    }

    public Task DeleteMessageAsync(Message message)
    {
        return Task.Factory.StartNew(() =>
            {
                MailingList mailinglist = message.MailingList;
                mailinglist.Message.Remove(message);

                _context.Messages.DeleteObject(message);
                _context.SaveChanges();
            });
    }
}
}

我想从一些简单的事情开始,以检查我是否知道大体上发生了什么。我创建了 WCF 服务库项目。我有IMessageService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using Newsletter.Common;

namespace WcfServiceLibrary
{
    [ServiceContract]
    public interface IMessageService
    {
        [OperationContract]
        void DeleteMessage(MessageDTO message);
    }
}

MessageService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using Newsletter.Common;
using Newsletter.DAL;
using System.Data.Entity;
using System.Data.Objects.DataClasses;

namespace WcfServiceLibrary
{
    public class MessageService : IMessageService
    {
        private NewsletterEntities _context;

        public MessageService()
        {
            _context = new NewsletterEntities();
        }

        public void DeleteMessage(MessageDTO messageDTO)
        {
            MailingList mailinglist = (from m in _context.MailingLists where m.MailingListID == messageDTO.MailingListID select m).FirstOrDefault();
            Message message = (from m in _context.Messages where m.MessageID == messageDTO.MessageID select m).FirstOrDefault();
            mailinglist.Message.Remove(message);

            _context.Messages.DeleteObject(message);
            _context.SaveChanges();
        }
    }
}

最后MessageDTO.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Newsletter.Common
{
    public class MessageDTO
    {
        public int MessageID { get; set; }
        public String Subject { get; set; }
        public String Content { get; set; }
        public bool HasAttachments { get; set; }
        public DateTime Date { get; set; }
        public int SenderID { get; set; }
        public int MailingListID { get; set; }
    }
}

我将其标记为启动项目并使用 WCF 测试客户端进行了试用。DeleteMessage()我用一些对象调用该方法,MessageID = 1并且MailingList = 5- 这些是我的数据库中特定记录的值。这就是我收到错误的关键点 - 来自 DAL 的未处理异常:

The specified named connection is either not found in the configuration, not intended to be used with the EntityClient provider, or not valid.并在停止调试器后:

An error occurred while receiving the HTTP response to http://localhost:8733/WcfServiceLibrary/MessageService/. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.

Server stack trace:     at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)    at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)    at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)    at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)    at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)    at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)    at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]:     at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)    at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)    at IMessageService.DeleteMessage(MessageDTO message)    at MessageServiceClient.DeleteMessage(MessageDTO message)

Inner Exception: The underlying connection was closed: An unexpected error occurred on a receive.    at System.Net.HttpWebRequest.GetResponse()    at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

Inner Exception: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.    at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)    at System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size)    at System.Net.Connection.SyncRead(HttpWebRequest request, Boolean userRetrievedStream, Boolean probeRead)

Inner Exception: An existing connection was forcibly closed by the remote host    at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)    at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)

App.configWCF:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. -->
  <system.serviceModel>
    <services>
      <service name="WcfServiceLibrary.MessageService">
        <endpoint address="" binding="basicHttpBinding" contract="WcfServiceLibrary.IMessageService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8733/WcfServiceLibrary/MessageService/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, 
          set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

</configuration>

我究竟做错了什么?一般方法可以吗?

4

2 回答 2

1

你的主要错误是

指定的命名连接在配置中未找到,不打算与 EntityClient 提供程序一起使用,或者无效。

您需要在配置文件中指定正确的连接字符串。

另一个错误是第一个错误的结果。

于 2012-12-07T00:11:15.953 回答
0

线索在错误消息中。您需要在配置文件中有一个连接字符串条目,以便 ef 知道从哪里获取其上下文

于 2012-12-06T21:59:59.567 回答