[英]WCF - How to correctly configure MVC Client consuming WCF Service?
I am perfectly aware that this problem has already been discussed a whole lot of times, but it is a specific configuration of my project that I miss to grasp which makes my Service - Client communication go wrong. 我完全意识到这个问题已经讨论了很多次,但是我错过了我的项目的特定配置,这使我的“服务-客户”通信出现问题。 I ask for your help in this matter.
在这件事上,我要求您的帮助。 Excuse my stupid errors, I am very new to WCF and REST services in general.
对不起我的愚蠢错误,我一般对WCF和REST服务还是陌生的。
So, basically, I want to create a MVC application that would consume a WCF REST service hosted on the IIS Server. 因此,基本上,我想创建一个MVC应用程序,该应用程序将使用IIS服务器上托管的WCF REST服务。
I have created a WCF Service Application with the following Service Contract : 我已经使用以下服务合同创建了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);
}
I implemented the methods correctly and in the web.config
file I configured the Service Model as such: 我正确地实现了这些方法,并在
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>
Afterwards, I published the WCF App on the IIS Server and it worked just fine returning the expected JSON format response in the browser. 之后,我在IIS服务器上发布了WCF应用程序,并且在浏览器中返回预期的JSON格式响应时,它运行良好。
I created a MVC app to whom I added a service reference to the published WCF service and named it UserServiceReference
. 我创建了一个MVC应用程序,向其中添加了对已发布的WCF服务的服务引用,并将其命名为
UserServiceReference
。 Strangely, no system.serviceModel
node was added or configured in the MVC's web.config
, so I added manually the following: 奇怪的是,没有在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>
Then I tried to test the functionality by creating a client in one of the app's controllers with the following code: 然后,我尝试通过使用以下代码在应用程序的一个控制器中创建客户端来测试功能:
UserServiceReference.UserServiceClient client = new UserServiceReference.UserServiceClient();
DataSet ds = client.DetaliiUtilizator("2");
UserServiceReference.UserDataContractUtilizator utilizator = new UserServiceReference.UserDataContractUtilizator();
When I run my app I get this error in the browser: 当我运行我的应用程序时,我在浏览器中收到此错误:
[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:
I added these things as a compilation of all the posts I have read. 我将这些内容添加为我已阅读的所有帖子的汇编。 It must be a certain error in all this code.
在所有这些代码中一定是某个错误。 What could it be?
会是什么呢?
Thank you so much! 非常感谢!
I have eventually realized which the problem was in this article: 我最终意识到本文中存在的问题:
https://blogs.msdn.microsoft.com/carlosfigueira/2012/03/25/mixing-add-service-reference-and-wcf-web-http-aka-rest-endpoint-does-not-work/ https://blogs.msdn.microsoft.com/carlosfigueira/2012/03/25/mixing-add-service-reference-and-wcf-web-http-aka-rest-endpoint-does-not-work/
It seems like adding a service reference to a WCF service with an endpoint using WebHttpBinding
will result in useless auto-generated Client code. 似乎使用
WebHttpBinding
向具有端点的WCF服务添加服务引用将导致无用的自动生成的客户端代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.