2010-12-03 62 views
2

是否可以創建「嵌入式」Web服務?我想要做的是創建一個.svc文件,該文件可以放置在IIS上的Web目錄中,並通過其URL訪問(並執行),無需安裝任何其他文件,也無需更改任何配置文件。是否可以創建完全包含在.svc文件中的ASP.NET Web服務?

我正在研究允許上傳.svc文件的Web應用程序中可能存在的安全問題。如果可以上傳並執行.svc文件,這對這個應用程序來說是一個很大的安全問題。不幸的是,我不是一個.NET開發人員,所以我可能在這裏錯過了很多東西。

我知道在「服務主機」指令之後,可以將服務接口和實現直接放入.svc文件中。這裏是我的.svc文件:

<%@ ServiceHost Language = "C#" Debug = "true" Service = "EchoService" %> 
public interface IEchoService 
{ 
    string Hello(); 
} 

public class EchoService : IEchoService 
{ 
    public string Hello() 
    { 
     return "Hello"; 
    } 
} 

現在,當我訪問http://localhost/test1.svc我從.NET異常:服務「EchoService的」具有零應用程序(非基礎設施)的端點。這可能是因爲沒有爲您的應用程序找到配置文件,或者因爲在配置文件中找不到匹配服務名稱的服務元素,或者因爲服務元素中沒有定義端點。

我明白,通常你應該在web.config或app.config文件中配置Web服務端點。從一些谷歌搜索我也瞭解到,可以通過定義自己的ServiceHost和ServiceCodeFactory以編程方式配置端點。我找到了一些例子,但無法讓它們工作。

如果有人能告訴我「不,你要做什麼是不可能的,因爲......」,或者說明我可以如何在上面的示例中添加必要的代碼來獲得可執行的服務。

更新:使用喬希的建議我終於得到它的工作。看到我的答案下面的工作代碼。

+0

與答案無關,但您可以採取一些措施來保護自己。您可以將所有上傳文件放入不允許運行腳本或可執行文件的目錄(IIS設置)。此外,您可以更改上傳代碼來過濾危險的擴展名,例如svc。 – Josh 2010-12-03 16:43:25

回答

1

好吧,我有一個包含在.svc文件中的可用的SOAP Web服務。這裏是代碼:

<%@ ServiceHost 
    Language = "C#" 
    Debug = "true" 
    Factory="Hello.CustomServiceHostFactory" 
    Service = "Hello.HelloService" %> 

using System; 
using System.ServiceModel; 
using System.ServiceModel.Activation; 

namespace Hello 
{ 

    public class CustomServiceHostFactory : ServiceHostFactory 
    { 

    public override System.ServiceModel.ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses) 
    { 
     return base.CreateServiceHost(constructorString, baseAddresses); 
    } 

     protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) 
     { 
     CustomHost host = new CustomHost(serviceType, baseAddresses); 

      //configure customServiceHost here 

     host.AddServiceEndpoint(typeof(IHelloService), new BasicHttpBinding(), ""); 

      var smb = host.Description.Behaviors.Find <System.ServiceModel.Description.ServiceMetadataBehavior>(); 
      if(smb == null) 
      { 
      // add the "get metadata" behavior 
      // This will allow the service to emit WSDL when tickled at the right HTTP endpoint 
      smb= new System.ServiceModel.Description.ServiceMetadataBehavior(); 
      smb.HttpGetEnabled = true; 
      host.Description.Behaviors.Add(smb); 
      }  
       return host; 
     } 
    } 

public class CustomHost : ServiceHost 
{ 

    public CustomHost() 
    { 
    } 

    public CustomHost(Type serviceType, params Uri[] baseAddresses) 
    : base(serviceType, baseAddresses) 
    { 
    } 


    public CustomHost(object singeltonInstance, params Uri[] baseAddresses) 
     : base(singeltonInstance, baseAddresses) 
{ 
} 

    protected override void ApplyConfiguration() 
    { 
    base.ApplyConfiguration(); 
    } 
} 

[ServiceContract(Namespace="http://www.example.com")] 
public interface IHelloService 
{ 
[OperationContract] 
    string Hello(); 
} 

public class HelloService : IHelloService 
{ 
    public string Hello() { 
     return "Hello"; 
    } 
} 
} 

它適用於.NET 4,不知道以前的版本。

0

我從來沒有這樣做過,但可能的解決方案是有一個ServiceHost工廠。我相信(不需要自己嘗試)您可以通過使用自定義服務主機公開的方法以編程方式配置ServiceHost

http://msdn.microsoft.com/en-us/library/bb332338.aspx

向下滾動到訪問的ServiceHost在IIS

清單5-6。帶有CustomServiceHostFactory的.svc文件

<% @ServiceHost Language="C#" Debug="true" 
Service="QuickReturns.StockTrading.ExchangeService.TradeService" 
Factory="QuickReturns.StockTrading.ExchangeService. 
TradeServiceCustomHostFactory" %> 

列表5-7。 TradeServiceCustomHostFactory和TradeServiceCustomHost

using System; 
using System.ServiceModel; 
using System.ServiceModel.Activation; 

namespace QuickReturns.StockTrading.ExchangeService 
{ 
    public class TradeServiceCustomHostFactory : ServiceHostFactory 
    { 
     protected override ServiceHost CreateServiceHost(
     Type serviceType, Uri[] baseAddresses) 
     { 
     TradeServiceCustomHost customServiceHost = 
      new TradeServiceCustomHost(serviceType, baseAddresses); 

     //configure customServiceHost here 

     return customServiceHost; 
     } 
    } 

    public class TradeServiceCustomHost : ServiceHost 
    { 
     public TradeServiceCustomHost(Type serviceType, params Uri[] 
baseAddresses) 
     : base(serviceType, baseAddresses) 
     { 
      //or configure here 
     } 

     protected override void ApplyConfiguration() 
     { 
     base.ApplyConfiguration(); 
     } 
    } 
} 

您可能可以將所有這些放到一個svc中。

+0

謝謝,我感謝你的幫助。我已經嘗試過這樣的事情 - 看問題更新,但我仍然卡住,但有一個不同的例外。 – Alla 2010-12-04 12:06:16

相關問題