在 WPF 应用程序中托管 WCF Web 服务

Posted

技术标签:

【中文标题】在 WPF 应用程序中托管 WCF Web 服务【英文标题】:Hosting WCF web service inside WPF application 【发布时间】:2012-03-16 06:01:57 【问题描述】:

我正在开发一个 WPF 应用程序。作为应用程序的一部分,我需要通过另一个 ios 应用程序接收一些图像。因此,我已经编写了 WCF REST 服务和 iOS,并且我能够将图像发送到 Web 服务只有在我将服务定义为 IIS 的一部分时。 我需要做的是:当 WPF 应用程序启动时,Web 服务也将启动,并为 iOS 设备公开一个端口号以发送图像并在启动时“唤醒”WPF 应用程序。 有什么想法吗?

【问题讨论】:

您是否考虑过在应用程序中自托管服务? 你有进步吗?我也有同样的情况。 【参考方案1】:

是的,我做到了。实际上正如蒂姆所提到的,这正是我所做的自托管服务。 你可以看看下面的视频(还有很多其他的,看看链接)。 http://channel9.msdn.com/shows/Endpoint/endpointtv-Screencast-Building-RESTful-Services-with-WCF/

以下是我的 WCF 项目中的完整文件:(如电影中所述),我希望它能帮助您入门。 请注意,在您的机器中打开特定端口以启用传入的 HTTP 流量也很重要。看看WCF ServiceHost access rights。

Eval.cs

[DataContract]
public class Eval

    public string id;

    [DataMember]
    public string Submitter;
    [DataMember]
    public DateTime Timesent;
    [DataMember]
    public string Comments;

IEvalService.cs

[ServiceContract]
public interface IEvalService

    [WebInvoke(Method="POST", UriTemplate = "evals")]
    [OperationContract]
    void SubmitEval(Eval i_Eval);

    [WebGet(UriTemplate = "evals")]
    [OperationContract]
    List<Eval> GetEvals();

    [WebGet(UriTemplate="eval/i_Id")]
    [OperationContract]
    Eval GetEval(string i_Id);

    [WebGet(UriTemplate = "evals/i_Submitter")]
    [OperationContract]
    List<Eval> GetEvalsBySubmitters(string i_Submitter);

    [WebInvoke(Method = "DELETE", UriTemplate = "eval/i_Id")]
    [OperationContract]
    void RemoveEval(string i_Id);

    [WebGet(UriTemplate = "GetLastPhoto", BodyStyle = WebMessageBodyStyle.Bare)]
    Stream GetLastPhoto();

    [OperationContract] // this web address is for receiving the image for the iOS app.
    [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "TestPost")]
    string TestPost(Stream stream);

EvalService.cs

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class EvalService : IEvalService

    private List<Eval> m_Evals = new List<Eval>();
    private int evalCount = 0;
    private string k_FilePath = "C:\\ImageUpload\\";

    public static event Action<LogicImage> ImageLoaded;

    public void SubmitEval(Eval i_Eval)
    
        i_Eval.id = (++evalCount).ToString();
        m_Evals.Add(i_Eval);
    

    public List<Eval> GetEvals()
    
        return m_Evals;
    

    public Eval GetEval(string i_Id)
    
        return m_Evals.First(e => e.id.Equals(i_Id));
    

    public List<Eval> GetEvalsBySubmitters(string i_Submitter)
    
        if (i_Submitter == null && i_Submitter.Equals(""))
        
            return null;
        

        else
        
            return m_Evals.Where(e => e.Submitter == i_Submitter).ToList();
        
    

    public void RemoveEval(string i_ID)
    
        throw new NotImplementedException();
    

    public Stream GetLastPhoto()
    
        Image image = Image.FromFile("C:\\ImageUpload\\014.png");
        MemoryStream ms = new MemoryStream(imageToByteArray(image));
        return ms;
    

    public string TestPost(Stream stream)
    
        HttpMultipartParser parser = new HttpMultipartParser(stream, "image");

        if (parser.Success)
        
            if (parser.Success)
            
                // deal with exceptions..
                //
                File.WriteAllBytes(k_FilePath + parser.Filename, parser.FileContents);
                if (ImageLoaded != null)
                
                    ImageLoaded.Invoke(new LogicImage()FileName = parser.Filename, Location = k_FilePath);
                
            
        

        return "test";
    

    public static byte[] imageToByteArray(System.Drawing.Image imageIn)
    
        MemoryStream ms = new MemoryStream();
        imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
        return ms.ToArray();
    


public class LogicImage

    public string FileName  get; set; 
    public string Location  get; set; 

最后但并非最不重要的** App.config**

<?xml version="1.0"?>
<configuration>

  <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="ImageRecevierWebService.EvalService">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8732/Design_Time_Addresses/ImageRecevierWebService/Service1/"/>
          </baseAddresses>
        </host>
        <!-- Service Endpoints -->
        <!-- Unless fully qualified, address is relative to base address supplied above -->
        <endpoint address="" binding="wsHttpBinding" contract="ImageRecevierWebService.IEvalService">
          <!-- 
              Upon deployment, the following identity element should be removed or replaced to reflect the 
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
              automatically.
          -->
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <!-- Metadata Endpoints -->
        <!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. --> 
        <!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="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>

<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

【讨论】:

以上是关于在 WPF 应用程序中托管 WCF Web 服务的主要内容,如果未能解决你的问题,请参考以下文章

如何从同一 WPF 应用程序托管的 WCF 服务调用 WPF 应用程序中的方法?

WPF 应用程序托管 WCF 访问冲突

WCF 服务作为 MVC 应用程序的一部分

在同一个 Web 应用程序中托管 WCF 服务和 Web API

使用 Windows 身份验证的 IIS 托管 WCF 服务和 SQL 查询

在 MVC Web 应用程序中托管 WCF 服务