2012-07-18 66 views
9

我有一個用C#構建的自定義HTTP服務器,它接受REST服務的請求並用XML或JSON響應(具體取決於客戶需要)。 REST服務是在運行時從基於數據庫的配置中定義的,在輸入參數和輸出類型方面差別很大,並且在生產中它的運行非常好。在C#中使用C#動態創建和公開SOAP服務及其WSDL(使用自定義TCP偵聽器)

但是,我想添加SOAP訪問相同的服務,以及適當的WSDLs。由於提供的服務沒有硬編碼,這意味着:

  • 發佈在從數據庫
  • 方法定義解析傳入的SOAP請求運行時生成一個WSDL,它們映射到這些定義,並確保該請求符合方法簽名處理它們
  • 一旦響應的處理之前,創建SOAP響應會議WDSL使用Visual Studio生成web返回結果

的MS文檔(和谷歌)文件Servi大街ces(和WSDLs),使用WebMethods,ASP.NET MVC等公開東西。這不是我正在尋找的,因爲不是方法定義,可以在設計時從中生成綁定。

有沒有人有任何想法(例如原始SOAP解析的工具包)以及從動態創建的方法簽名等生成WSDL的想法?任何想法如何可以去建設這樣的事情,如果不是?我希望儘可能避免重新發明車輪。

PS:很顯然,在.NET框架中存在標準化的東西,因爲Visual Studio爲你做了 - 任何想法如何在運行時在較低的級別訪問它?

+1

之間發送SOAP(XML)格式的想法_ _「的REST服務是在運行時從一個基於數據庫的配置定義」 - 當我讀到我瑟瑟發抖。這不是一個維護和故障排除嗎? – CodeCaster 2012-07-23 10:06:54

+0

我處理一個非常類似的情況想,如果接受的答案爲你工作 – 2012-10-14 06:15:57

+0

NP難 - 我做了一個驗證的概念,它做了什麼之意。我沒有任何東西滾出去到生產,不過,作爲平衡要求客戶實現REST服務似乎是一個更可靠的選擇,而不是手動解析,並且可以通過手動解析SOAP請求的複雜過程中引入任何錯誤。 – 2012-10-14 10:18:56

回答

6

要動態創建一個WSDL可以使用ServiceDescriptionReflector

例如:

public class TestWebService 
{ 
    [WebMethod] 
    public string Hello(string namex) 
    { 
     return "Hello " + namex; 
    } 
} 

您可以使用此代碼

StringWriter wr = new StringWriter(); 
var r = new System.Web.Services.Description.ServiceDescriptionReflector(); 
r.Reflect(typeof(TestWebService), "http://somewhere.com"); 
r.ServiceDescriptions[0].Write(wr); 
var wsdl = wr.ToString(); 

但既然你已經說過

Publishin GA WSDL在運行時所產生的方法定義數據庫

你必須在運行時創建Type

var asm = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("MyAsm"), AssemblyBuilderAccess.Run); 
var mod = asm.DefineDynamicModule("MyModule"); 

TypeBuilder typeBuilder = mod.DefineType("TestWebService"); 

MethodBuilder mb = typeBuilder.DefineMethod("Hello", MethodAttributes.Public, CallingConventions.Standard, typeof(string), new Type[] { typeof(string) }); 
var cab = new CustomAttributeBuilder(typeof(WebMethodAttribute).GetConstructor(new Type[]{}), new object[]{}); 
mb.SetCustomAttribute(cab); 
mb.DefineParameter(1, ParameterAttributes.In, "namex"); 
mb.GetILGenerator().Emit(OpCodes.Ret); 

Type type = typeBuilder.CreateType(); 

現在你可以使用type創建WSDL

StringWriter wr = new StringWriter(); 
var r = new System.Web.Services.Description.ServiceDescriptionReflector(); 
r.Reflect(type, "http://somewhere.com"); 
r.ServiceDescriptions[0].Write(wr); 
var wsdl = wr.ToString(); 

對於閱讀請求並形成響應,您可以使用Linq2Xml。 Fiddler可以爲您提供有關客戶端和服務器

+0

這是偉大的 - 我已經得到了創造型整理出來,但ServiceDescriptionReflector正是我一直在尋找。謝謝! – 2012-07-26 08:04:47

2

SOAP僅僅是一個基於XML的信息交換協議。從原則上實施對它的支持將是乏味的,但原則上並不複雜,我不這麼認爲。

官方SOAP規範可以找到here

+0

這主要是單調(和潛在的bug),我期待,以避免 - 而希望某種工具的處理SOAP解析等。我知道微軟大約10年前,有自己的SOAP工具包,但它贊成不贊成VS管理一切......不過謝謝! – 2012-07-19 08:08:48

2

不解析SOAP,除非你真的要,讓WCF爲你做繁重,從您的定義生成C#代碼服務 - 和datacontracts和編譯在運行時。生成一個服務實現,通過一個衆所周知的接口將其綁定到您的「靜態」代碼中。

動態創建具有新服務合同/數據合同正確綁定的端點。如果綁定不會動態改變,可以在你的app.config中定義,否則在運行時設置它。

添加一個Mex端點以獲得發佈的wsdl。

對於 「檢查」 的傳入流量使用MessageInspector

自主辦HTTP服務器使用的ServiceHost的WCF/SOAP服務 - >Self Hosting WCF

上的另一種方法只是一些想法。

+0

從我原來的問題來看,這可能不夠清楚,但數據合同和綁定*在運行時都會更改,這就是爲什麼我沒有使用WCF。這就是這裏的用例 - 一個非WCF/IIS服務器以及在運行時更改(並且經常創建)的契約。 – 2012-07-23 14:25:43

+0

如果合同和綁定都會改變您的客戶如何使用您的服務?必須很難找到服務? – 2012-07-23 15:43:50

+0

我得到的動態合約位,它是由動態生成的合同處理,作爲使用,你可以自行舉辦WCF/SOAP服務在您的HTTP服務器託管的ServiceHost http://msdn.microsoft.com/en-us/庫/ ms730158.aspx。 – 2012-07-23 16:06:49

相關問題