如何在我的项目中实现WCF?

时间:2012-12-06 21:52:15

标签: c# .net wcf entity-framework

我有一个通过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)
WCF的

App.config

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

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

2 个答案:

答案 0 :(得分:1)

您的主要错误是

  

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

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

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

答案 1 :(得分:0)

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