无法正确配置 WCF Restful/json 端点

Can't configure WCF Restful/json endpoints correctly

我创建了一个 restful 服务,并能够让它在收到 XML 请求时生成 JSON 响应,但我需要它来接受 JSON 请求。我调整了流程但遇到了问题,因为我最初有调用多个服务的主要服务,每个服务都有自己的 C# 接口。它告诉我必须明确命名端点,然后所有这些都进入了垃圾堆。我最终放弃了调用多个服务,转而使用具有多个操作合约调用方法的单个服务。

现在我只收到一条简单的 "endpoint not found" 消息。我真的,真的不明白端点定义的来龙去脉。

这是我的主要服务页面 (AgtDash.svc) 上的代码。我们正在调用 "agent dashboard"

的统计数据

编辑 - 更新了代码以反映 URI 模板引用,没有做任何更改,并更改了 web.config 中的服务名称引用。现在错误不再是 "endpoint not found",而是 404 引用。

namespace AgentDashboard
{

    public class AgtDash : dashboardInfo
    {

        public string GetAgencyInfo(agcInfoInput agcInput)
        {
            string agInfo = string.Empty;

            (RETRIEVES DATA TABLE)

            agInfo = tableToJson(agcTable);
            return agInfo;
        }

        public string GetAgencyDetails(agcInfoInput agcInput)
        {
            string agcyInfo = string.Empty;

            (RETRIEVES DATA TABLE)

            agcyInfo = tableToJson(agcTable);
            return agcyInfo;
        }

        public string GetAgencyTotals(agcInfoInput agcInput)
        {
            string agcyTot = string.Empty;

            (RETRIEVES DATA TABLE)

            agcyTot = tableToJson(agcTable);
            return agcyTot;
        }

        public string GetAgentTotals(agtInfoInput agtInput)
        {
            (RETRIEVES DATA TABLE)

                agtInfo = tableToJson(agTable);
            return agtInfo;
        }

        public string tableToJson(DataTable inpTable)
        {
            var jsString = new StringBuilder();

            (CONVERTS DATA TABLE TO JSON RESPONSE)

            return jsString.ToString();
        }
    }
}

这是我的界面:

namespace AgentDashboard
{
    [ServiceContract]
    public interface dashboardInfo
    {
        [OperationContract]
        [WebInvoke(UriTemplate="/GetAgentTotals",
            Method = "POST",
            RequestFormat = WebMessageFormat.Json,
            ResponseFormat = WebMessageFormat.Json,
            BodyStyle = WebMessageBodyStyle.Wrapped)]

        string GetAgentTotals(agtInfoInput agentInput);

        [OperationContract]

        [WebInvoke(UriTemplate="/GetAgencyInfo",
            Method = "POST",
            RequestFormat = WebMessageFormat.Json,
            ResponseFormat = WebMessageFormat.Json,
               BodyStyle = WebMessageBodyStyle.Wrapped)]

        string GetAgencyInfo(agcInfoInput agencyInput);

        [OperationContract]

        [WebInvoke(UriTemplate="/GetAgencyDetails",
        Method = "POST",
        RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Wrapped)]

        string GetAgencyDetails(agcInfoInput agencyInput);

        [OperationContract]

        [WebInvoke(UriTemplate="/GetAgentTotals",
            Method = "POST",
            RequestFormat = WebMessageFormat.Json,
            ResponseFormat = WebMessageFormat.Json,
            BodyStyle = WebMessageBodyStyle.Wrapped)]

        string GetAgencyTotals(agcInfoInput agencyInput);
    }


    [DataContract]
    public class agtInfoInput
    {
        [DataMember]
        public string id { get; set; }

        [DataMember]
        public int year { get; set; }

    }

    [DataContract]
    public class agcInfoInput
    {
        [DataMember]
        public int id { get; set; }

        [DataMember]
        public int year { get; set; }

    }
}

我的网络配置:

<system.serviceModel>
    <client>
      <endpoint binding="webHttpBinding" contract="AgentDashboard.dashboardInfo" />
    </client>
    <services>
      <service name="AgentDashboard.AgtDash">
        <endpoint address="dashboardInfo" binding="webHttpBinding" behaviorConfiguration="webBehavior" contract="AgentDashboard.dashboardInfo" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        <host>
          <baseAddresses>
            <add baseAddress="AgtDash.svc" />
          </baseAddresses>
        </host>       
      </service>
    </services>
    <bindings>
      <webHttpBinding>
        <binding>
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
          </security>
        </binding>
      </webHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="webBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>      
    </behaviors>
  </system.serviceModel>

我确定 web.config 是一团乱麻。我什么时候需要使用端点详细信息来定义服务?什么时候使用客户端配置?我什么时候使用两者?当我最初有多个客户端端点时,它似乎在本地工作正常,但当它告诉我必须定义服务时,我选择了那条路线。

很抱歉,如果有答案,但它们的解决方案都非常不同,并且没有让我深入了解原因。最终,这将驻留在自己的 Web application/directory 中,由 IIS 提供服务,并且需要接收和发送 JSON。 JSON 响应的生成似乎有效,它正确识别了端点,这阻止了我对它进行全面测试,因为我无法正确识别目标,可以这么说。

如果您对 web.config 有任何疑问,请告诉我。提前致谢。

当前错误:

尝试像这样添加 UriTemplate:

      [OperationContract]
      [WebInvoke(UriTemplate="/GetAgentTotals",
      Method = "POST",
      RequestFormat = WebMessageFormat.Json,
      ResponseFormat = WebMessageFormat.Json,
      BodyStyle = WebMessageBodyStyle.Wrapped)]

      string GetAgentTotals(agtInfoInput agentInput)

注意带有方法名称的 UriTemplate。

这将帮助客户端找到正确的操作映射。

当我执行 webHttpBinding 时,我通常必须添加 UriTemplate。

最后说明:

为了转换现有的 WCF 以支持 json 这很好...但是对于新服务我只使用 ASP.NET 核心。它对 JSON 和许多其他功能有更好的支持。

特别是如果您只需要 HTTP。

无需定义额外的服务端点。根据您的配置,operation/methods 应采用以下形式。

Http://host:portnumber/AgtDash.svc/dashboardInfo/GetAgentTotals
Http://host:portnumber/AgtDash.svc/dashboardInfo/GetAgentInfo
Http://host:portnumber/AgtDash.svc/dashboardInfo/GetAgencyDetails   
Http://host:portnumber/AgtDash.svc/dashboardInfo/GetAgencyTotals.  

调用时,在Body部分附加参数,使用Post Http动词。 Webconfig 中配置的服务基础可以忽略。由IIS站点绑定决定。
如果有什么我可以帮忙的,请随时告诉我。
已更新。
<service name="AgentDashboard.AgentDashInfo"> 替换为 <service name=”AgentDashboard.AgtDash”>。这里应该配置已实现的 class with namespace。