【问题标题】:WCF - How to correctly configure MVC Client consuming WCF Service?WCF - 如何正确配置使用 WCF 服务的 MVC 客户端?
【发布时间】:2016-11-28 14:54:43
【问题描述】:

我完全清楚这个问题已经讨论过很多次了,但是我错过了我项目的一个特定配置,这导致我的服务 - 客户端通信出错。我在这件事上请求你的帮助。请原谅我的愚蠢错误,总的来说,我对 WCF 和 REST 服务非常陌生。

所以,基本上,我想创建一个 MVC 应用程序,它会使用托管在 IIS 服务器上的 WCF REST 服务。

我使用以下服务合同创建了一个 WCF 服务应用程序:

[ServiceContract]
public interface IUserService
{
    [OperationContract]
    [WebInvoke(Method = "GET",
        ResponseFormat = WebMessageFormat.Json,
        RequestFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Wrapped,
        UriTemplate = "/ListaUtilizatori/")]
    DataSet ListaUtilizatori();

    [OperationContract]
    [WebInvoke(Method = "GET",
        ResponseFormat = WebMessageFormat.Json,
        RequestFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Wrapped,
        UriTemplate = "/DetaliiUtilizator/{id}")]
    DataSet DetaliiUtilizator(String id);


    [OperationContract]
    [WebInvoke(Method = "POST",
        ResponseFormat = WebMessageFormat.Json,
        RequestFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Wrapped,
        UriTemplate = "/AdaugaUtilizator")]
    String AdaugaUtilizator(Utilizator utilizator);

    [OperationContract]
    [WebInvoke(Method = "PUT",
      RequestFormat = WebMessageFormat.Json,
      ResponseFormat = WebMessageFormat.Json,
      UriTemplate = "/ActualizeazaUtilizator")]
    String ActualizeazaUtilizator(Utilizator utilizator);

    [OperationContract]
    [WebInvoke(Method = "DELETE",
       RequestFormat = WebMessageFormat.Json,
       ResponseFormat = WebMessageFormat.Json,
       UriTemplate = "/StergeUtilizator/{id}")]
    String StergeUtilizator(String id);
}

我正确地实现了这些方法,并在web.config 文件中这样配置了服务模型:

<system.serviceModel>
    <services>
      <service name="RESTService.UserService" behaviorConfiguration="RESTServiceBehaviour">
        <endpoint address="" binding="webHttpBinding" bindingConfiguration="WebHttpBinding_IUserService" contract="RESTService.IUserService" behaviorConfiguration="RESTEndpointBehavior"></endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>        
        <behavior name="RESTServiceBehaviour">
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="RESTEndpointBehavior">
          <webHttp helpEnabled="True"/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <webHttpBinding>
        <binding name="WebHttpBinding_IUserService" />
      </webHttpBinding>
    </bindings>
    <protocolMapping>
        <add binding="webHttpBinding" scheme="http" />
    </protocolMapping>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

之后,我在 IIS 服务器上发布了 WCF 应用程序,它运行良好,在浏览器中返回了预期的 JSON 格式响应。

我创建了一个 MVC 应用程序,我向该应用程序添加了对已发布 WCF 服务的服务引用,并将其命名为 UserServiceReference。奇怪的是,在MVC的web.config中没有添加或配置system.serviceModel节点,所以我手动添加了以下内容:

<system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="RESTEndpoint">
          <webHttp helpEnabled="true"/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <webHttpBinding>
        <binding name="WebHttpBinding_IUserService" />        
      </webHttpBinding>      
    </bindings>
    <client>
      <endpoint address="http://localhost/RESTUserService/UserService.svc" binding="webHttpBinding" bindingConfiguration="WebHttpBinding_IUserService" 
                behaviorConfiguration="RESTEndpoint" contract="UserServiceReference.IUserService" name="WebHttpBinding_IUserService" />
    </client>
</system.serviceModel>

然后我尝试通过使用以下代码在应用程序的控制器之一中创建客户端来测试功能:

UserServiceReference.UserServiceClient client = new UserServiceReference.UserServiceClient();
            DataSet ds = client.DetaliiUtilizator("2");
UserServiceReference.UserDataContractUtilizator utilizator = new UserServiceReference.UserDataContractUtilizator();

当我运行我的应用程序时,我在浏览器中收到此错误:

[WebException: The remote server returned an error: (404) Not Found.]  System.Net.HttpWebRequest.GetResponse() +1390    System.ServiceModel.Channels.HttpChannelRequest.WaitForReply(TimeSpan timeout) +55

[EndpointNotFoundException: There was no endpoint listening at http://localhost/RESTUserService/UserService.svc/DetaliiUtilizator that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.]
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +153



System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +336
   MVCApp.UserServiceReference.IUserService.DetaliiUtilizator(String id) +0
   MVCApp.UserServiceReference.UserServiceClient.DetaliiUtilizator(String id) in D:\F5IT\PROJECT\RESTService\MVCApp\Service References\UserServiceReference\Reference.cs:308
   MVCApp.Controllers.HomeController.Index() in D:\F5IT\PROJECT\RESTService\MVCApp\Controllers\HomeController.cs:34
   lambda_method(Closure , ControllerBase , Object[] ) +61
   System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +14
   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +157
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
   System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +22
   System.Web.Mvc.Async.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) +29
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32
   System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d() +50
   System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +225
   System.Web.Mvc.Async.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34
   System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +26
   System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +100
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
   System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +36
   System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +12
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +22
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26
   System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
   System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9744373
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
Source Error: 

Line 306:        
Line 307:        public System.Data.DataSet DetaliiUtilizator(string id) {
Line 308:            return base.Channel.DetaliiUtilizator(id);
Line 309:        }
Line 310:     

我将这些内容添加为我已阅读的所有帖子的汇编。在所有这些代码中一定是某个错误。会是什么呢?

非常感谢!

【问题讨论】:

  • 来自错误:See InnerException, if present, for more details.
  • @JamieR 我添加了整个异常。
  • 您确定http://localhost/RESTUserService/UserService.svc/DetaliiUtilizator 是正确的端点吗?
  • 不,端点是http://localhost/RESTUserService/UserService.svc/DetaliiUtilizator /{id},所以代码中的方法有参数。

标签: asp.net-mvc wcf webhttpbinding wcf-configuration


【解决方案1】:

我终于意识到这篇文章的问题所在:

https://blogs.msdn.microsoft.com/carlosfigueira/2012/03/25/mixing-add-service-reference-and-wcf-web-http-a-k-a-rest-endpoint-does-not-work/

似乎将服务引用添加到使用WebHttpBinding 的端点的 WCF 服务将导致无用的自动生成客户端代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-24
    • 1970-01-01
    • 2010-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多