无法正确配置 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。
我创建了一个 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。