简体   繁体   中英

WCF Service metadata publishing error

I am new to WCF and trying to get it up and running. I cant even get a blank version without any errors.

web.config:

 <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="ServiceAspNetAjaxBehavior">
          <enableWebScript />
        </behavior>

        <!--wcf-->     
        <behavior name="recordsWCF">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="recordsSWCF" >
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    <!--end wcf-->      

    </behaviors> 
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />   
    <services>


      <!--wcf-->
      <service name="records.wcf" behaviorConfiguration="recordsSWCF" >
        <!--<endpoint address="" binding="webHttpBinding" contract="IService" behaviorConfiguration="recordsWCF"/>-->
        <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
      </service>
      <!--end wcf-->         

      <service name="Service">
        <endpoint address="" behaviorConfiguration="ServiceAspNetAjaxBehavior" binding="webHttpBinding" contract="Service" />
      </service>
    </services>
  </system.serviceModel>

As far as my wcf code, there isn't much to do...yet. I am just trying to learn how to setup the web.config without any errors. And here is my wcf definition:

[ServiceContract(Namespace = "records")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class wcf
{

 public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }      
    [OperationContract]
    [WebGet]
    public string GetData()
    {
        Person p = new Person();
        List<Person> test = new List<Person>();
        p.Name = "Tom";
        p.Age = 28;   
        test.Add(p);   
        p = new Person();
        p.Name = "Dan";
        p.Age = 22;
        test.Add(p);
        JavaScriptSerializer js = new JavaScriptSerializer();   
        string jsonString = js.Serialize(test);    

        return jsonString;
    }    
}

Although it is commented out in the records.wcf service section of your web.config, it looks like the endpoint you are exposing (or going to expose) is a webHttpBinding endpoint, which is a REST binding. The WCF metadata exchange endpoint is for SOAP endpoints only (eg basicHttpBinding or wsHttpBinding). There is no way to get metadata out of WCF REST services like this.

If you need metadata, you have two options:

  1. Refactor your service to be a SOAP service
  2. Instead of WCF, use the ASP.Net Web API. This is purpose-built for REST and gives you an auto-generated help page which is conceptually the same as the metadata endpoint in WCF

Judging from your question, the metadata isn't really the objective, it is just a way of checking if your service is coming along OK. If this is the case, you need to

  1. Delete the serviceMetadata element from your recordWCF service behavior
  2. Delete the IMetadatExchange endpoint
  3. Add the service endpoint

Your web.config should look like this:

  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>

        <!--wcf-->
        <behavior name="recordsWCF">
          <webHttp/>
          <enableWebScript />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="recordsSWCF" >
          <!--<serviceMetadata httpGetEnabled="true" />-->
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
      <!--end wcf-->

    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
    <services>


      <!--wcf-->
      <service name="records.Service" behaviorConfiguration="recordsSWCF" >
        <endpoint address="" binding="webHttpBinding" contract="records.Service" behaviorConfiguration="recordsWCF"/>
        <!--<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />-->
      </service>
      <!--end wcf-->
    </services>
  </system.serviceModel>

And the class implementing the service should look like this

using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Web.Script.Serialization;

namespace records
{
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceContract]
    public class Service
    {
        public class Person
        {
            public string Name { get; set; }
            public int Age { get; set; }
        }

        [WebGet]
        public string GetData()
        {
            Person p = new Person();
            List<Person> test = new List<Person>();
            p.Name = "Tom";
            p.Age = 28;
            test.Add(p);
            p = new Person();
            p.Name = "Dan";
            p.Age = 22;
            test.Add(p);
            JavaScriptSerializer js = new JavaScriptSerializer();
            string jsonString = js.Serialize(test);

            return jsonString;
        }
    }
}

The markup for your .svc should look something like

<%@ ServiceHost Language="C#" Debug="true" Service="records.Service" CodeBehind="Service.svc.cs" %>

With that configuration, when I browse to http://localhost:56157/Service.svc/GetData I get

[{"Name":"Tom","Age":28},{"Name":"Dan","Age":22}]

you have to do this in Chrome, not IE. If you try it in IE it tries to open the JSON as a file.

Note that it is a bit unusual to have the service contract defined on the same class that implements the service. More commonly the service contract is defined on an interface (eg IService) and implemented in a class (eg public class Service : IService).

Also, unless there is a particular reason for using WCF (eg you want to do a SOAP service), I would strongly recommend the ASP.Net Web API for REST services. I know a lot more about WCF than ASP.Net generally and still I find it much easier to do REST with ASP.Net Web API.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM