2012-04-05 2 views
3

するための構成を経由して適切にREST XML、REST JSONおよびSOAPを公開することはできません、私は次のことを実現するWCFサービスを構築することができるようにしたいんだ:だけWCF

  • はRESTfulにRESTfulにJSON
  • を公開します公開するXML
  • は、SOAPに
  • その他のバインディングを公開している場合、必要な

ここで重要なのは、私はこのすべてをしたいということですコードResponseFormat=ResponseFormat.JsonまたはResponseFormat=ResponseFormat.Xmlで個別にRESTfulメソッドの個別の関数を指定する必要はなく、必要なメソッドごとにコードで記述された関数は1つだけです。私はたくさんの研究をしてきましたが、純粋に構成によって可能かどうかは確かではありません。

奇妙なことに、URLを使ってアクセスするとRESTfulメソッドが動作しますが、WSDLはエラーをスローします。つまり、SOAP経由でサービスを参照/消費したい場合、WSDLで失敗します。インポートステップ。

サービスのコードは以下のとおりであり、構成はサービスであり、サービスはhttp://localhost/WCFのテスト用にローカルにホストされています。以下の2つのRESTfulな呼び出しが正常に動作し、ブラウザに成功したXMLとJSONを返す:

はlocalhost/WCF/service1.svc/JSON /学生

はlocalhost/WCF/service1.svc /休憩/学生

しかし、私がhttp://localhost/WCF/service1.svc?wsdlと呼ぶと、私は以下のエラーが出ます。 webhttpBindingエンドポイント設定の1つを削除すると、WSDLが正しく動作して表示されるため、参照することができます。

WSDLの生成を有効にするには、config内に複数のwebHttpBindings(つまり、別のメソッドと属性(ResponseFormat=ResponseFormat.Jsonなど)を使用する必要があります)を使用することはできませんか?または、ここで間違った設定をしましたか?

何か助けていただければ、設定を介してシリアライゼーションが指定された特別な機能を使用する方がはるかに簡単です。ありがとう。

WSDL生成エラー

An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is: 
    System.NullReferenceException: Object reference not set to an instance of an object. 
     at System.ServiceModel.Description.WsdlExporter.CreateWsdlBindingAndPort(ServiceEndpoint endpoint, XmlQualifiedName wsdlServiceQName, Port& wsdlPort, Boolean& newBinding, Boolean& bindingNameWasUniquified) 
     at System.ServiceModel.Description.WsdlExporter.ExportEndpoint(ServiceEndpoint endpoint, XmlQualifiedName wsdlServiceQName) 
     at System.ServiceModel.Description.WsdlExporter.ExportEndpoints(IEnumerable`1 endpoints, XmlQualifiedName wsdlServiceQName) 
     at System.ServiceModel.Description.ServiceMetadataBehavior.MetadataExtensionInitializer.GenerateMetadata() 
     at System.ServiceModel.Description.ServiceMetadataExtension.EnsureInitialized() 
     at System.ServiceModel.Description.ServiceMetadataExtension.get_Metadata() 
     at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.InitializationData.InitializeFrom(ServiceMetadataExtension extension) 
     at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.GetInitData() 
     at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.TryHandleMetadataRequest(Message httpGetRequest, String[] queries, Message& replyMessage) 
     at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.ProcessHttpRequest(Message httpGetRequest) 
     at SyncInvokeGet(Object , Object[] , Object[]) 
     at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) 
     at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) 
     at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) 
     at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc) 
     at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet) 

のWeb.config

<?xml version="1.0"?> 
<configuration> 
    <system.web> 
    <compilation debug="true" targetFramework="4.0" /> 
    </system.web> 
    <system.serviceModel> 
    <services> 
     <service behaviorConfiguration="httpGetBehavior" name="WCF.Service1"> 
     <endpoint address="json" binding="webHttpBinding" name="jsonRest" contract="WCF.IService1" behaviorConfiguration="jsonBehavior"></endpoint> 
     <endpoint address="rest" binding="webHttpBinding" name="xmlRest" contract="WCF.IService1" behaviorConfiguration="restBehaviour"></endpoint> 
     <endpoint address="soap" binding="basicHttpBinding" name="soap" contract="WCF.IService1"></endpoint> 
     <endpoint name="mex" address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
     <host> 
      <baseAddresses> 
      <add baseAddress="http://localhost/WCF"/> 
      </baseAddresses> 
     </host> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="httpGetBehavior"> 
      <serviceMetadata httpGetEnabled="true"/> 
     </behavior> 
     </serviceBehaviors> 
     <endpointBehaviors> 
     <behavior name="jsonBehavior"> 
      <webHttp defaultOutgoingResponseFormat="Json"/> 
     </behavior> 
     <behavior name="restBehaviour"> 
      <webHttp/> 
     </behavior> 
     </endpointBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> 
    </system.serviceModel> 
<system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"/> 
    </system.webServer> 
</configuration> 

コード

public class Service1 : IService1 
{  
    public IList<Student> GetStudents() 
    { 
     IList<Student> students = new List<Student>(); 
     students.Add(new Student() { FirstNme = "Bob", LastName = "Long", StudentId = 1, Subject = "Economics" }); 
     students.Add(new Student() { FirstNme = "Jack", LastName = "Short", StudentId = 2, Subject = "IT" }); 
     return students; 
    } 
} 

[ServiceContract] 
public interface IService1 
{  
    [WebGet(UriTemplate = "/students")] 
    [OperationContract] 
    IList<Student> GetStudents(); 

} 

[DataContract] 
public class Student 
{ 
    private int _studentId; 
    private string _firstName; 
    private string _lastName; 
    private string _subject; 

    [DataMember] 
    public int StudentId 
    { 
     get { return _studentId; } 
     set { _studentId = value; } 
    } 

    [DataMember] 
    public string FirstNme 
    { 
     get { return _firstName; } 
     set { _firstName = value; } 
    } 

    [DataMember] 
    public string LastName 
    { 
     get { return _lastName; } 
     set { _lastName = value; } 
    } 

    [DataMember] 
    public string Subject 
    { 
     get { return _subject; } 
     set { _subject = value; } 
    } 
} 

答えて

3

は、これは既知の問題ヘクタールであります単一のサービスのving json、xmlおよびsoapエンドポイントは例外をスローします。

MS Connectでエラーとして報告しました。

フレームワークを3.5に切り替えると、それが機能するか回避策が提供されます。リクエストオブジェクトからコンテンツヘッダを取得し、コード内でレスポンスフォーマットを設定し、レスポンスをそれに応じて返すことができます。

また、Web APIでは、WebGet/WebInvoke属性に何も指定されていない場合、フレームワークは自動的にコンテンツタイプに基づいてこれを判断し、それに応じて応答を返します。

NOTE:MS Connectでリンクを開くときに、MS Connectサイトでシステムエラーが発生します。回避策をご希望の場合は、私がそれを送ることができることを教えてください。また、MSは、多くのクライアントが3つのフォーマットをすべて単一のサービスに公開したくないので、修正するつもりはないことを確認しました。

+0

フィードバックをいただきありがとうございました。私は実際には、最終的にこれを他の場所でもあいまいに見つけることができましたが、見つけるのは簡単ではないようです。リクエストのコンテンツタイプの回避策は、ここでは良い選択肢のように聞こえます。 – Fitzroy79

+0

WebAPIはwsdlを提供しません – PositiveGuy

2

私は、SOAP、JSON、およびXMLエンドポイントを持つ非常に単純なサービスを作成しました。そのシンプルさのためにのみ機能しますか?

私は、jsonとxmlのために別々のバインディング設定(空ではあるが)を宣言しなければならないことを知りました。これは、サービス契約である

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

    <system.web> 
    <compilation debug="true" targetFramework="4.0"/> 
    </system.web> 

    <system.serviceModel> 

    <bindings> 
     <webHttpBinding> 
     <!-- separate bindings are necessary --> 
     <binding name="jsonBinding"/> 
     <binding name="xmlBinding"/> 
     </webHttpBinding> 
    </bindings> 

    <behaviors> 
     <serviceBehaviors> 
     <behavior> 
      <serviceMetadata httpGetEnabled="true"/> 
      <serviceDebug includeExceptionDetailInFaults="true"/> 
     </behavior> 
     </serviceBehaviors> 

     <endpointBehaviors> 
     <behavior name="xmlEndpoint"> 
      <webHttp helpEnabled="true" defaultOutgoingResponseFormat="Xml"/> 
     </behavior> 
     <behavior name="jsonEndpoint"> 
      <!-- do not specify enableWebScript or UriTemplate will not work --> 
      <webHttp helpEnabled="true" defaultOutgoingResponseFormat="Json"/> 
     </behavior> 
     </endpointBehaviors> 
    </behaviors> 

    <services> 
     <service name="Services.Addressbook.AddressbookService"> 
     <endpoint address="" binding="basicHttpBinding" name="soap" contract="Services.Addressbook.IAddressbookService" /> 
     <endpoint address="mex" binding="mexHttpBinding" name="mex" contract="IMetadataExchange" /> 
     <endpoint address="json" behaviorConfiguration="jsonEndpoint" binding="webHttpBinding" bindingConfiguration="jsonBinding" name="restJson" contract="Services.Addressbook.IAddressbookService" /> 
     <endpoint address="xml" behaviorConfiguration="xmlEndpoint" binding="webHttpBinding" bindingConfiguration="xmlBinding" name="restXml" contract="Services.Addressbook.IAddressbookService" /> 
     </service> 
    </services> 

    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/> 

    </system.serviceModel> 

    <system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"/> 
    </system.webServer> 

</configuration> 

::ここで(のみsystem.serviceModelセクションが前に見えていたので、更新、)構成がある

[ServiceContract] 
public interface IAddressbookService { 
    [OperationContract] 
    [WebGet(UriTemplate = "Version")] 
    string GetVersion(); 

    [OperationContract] 
    [WebGet(UriTemplate = "Entries/Count")] 
    int GetEntriesCount(); 

    [OperationContract] 
    [WebGet(UriTemplate = "Entries")] 
    Address[] GetEntries(); 

    [OperationContract] 
    [WebGet(UriTemplate = "Entries/{name}")] 
    Address[] SearchEntriesByName(string name); 

    [OperationContract] 
    [WebInvoke(Method = "POST", UriTemplate = "Entries/Add")] 
    bool AddEntry(Address entry); 

    [OperationContract] 
    [WebInvoke(Method = "DELETE", UriTemplate = "Entries/Remove")] 
    bool RemoveEntry(Address entry); 
} 

そして、ここでデータコントラクトです:

[DataContract] 
public class Address { 
    [DataMember] 
    public string FirstName { get; set; } 
    [DataMember] 
    public string LastName { get; set; } 
    [DataMember] 
    public string Street { get; set; } 
    [DataMember] 
    public string City { get; set; } 
    [DataMember] 
    public int ZipCode { get; set; } 
    [DataMember] 
    public string Country { get; set; } 
    [DataMember] 
    public string Phone { get; set; } 
    [DataMember] 
    public string Email { get; set; } 
} 
+0

.NET 3.5または.NET 4にはありますか? – Rajesh

+0

私が対象とした.Net Framework 4でこれをテストしたプロジェクト – Andreas

1

てみてくださいthis

<bindings> 
    <webHttpBinding> 
    <binding name="webBindingXML"></binding> 
    <binding name="webBindingSOAP"></binding> 
    </webHttpBinding> 
</bindings>