![](/img/trans.png)
[英]System.InvalidOperationException when calling WCF Service
[英]InvalidOperationException when calling a WCF RESTful service method with multiple arguments?
對於名為AuthenticationService
的服務,我具有以下代碼:
IAuthenticationService.cs
[ServiceContract]
public interface IAuthenticationService
{
[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
bool Login(string username, string password, string applicationName);
}
AuthenticationService.svc.cs
public sealed class AuthenticationService : IAuthenticationService
{
public bool Login(string username, string password, string applicationName)
{
// TODO: add the logic to authenticate the user
return true;
}
}
Web.config文件
<system.serviceModel>
<!-- START: to return JSON -->
<services>
<service name="ImageReviewPoc.Service.AuthenticationService">
<endpoint contract="ImageReviewPoc.Service.Contracts.IAuthenticationService" binding="webHttpBinding" behaviorConfiguration="jsonBehavior"/>
</service>
</services>
<!-- END: to return JSON -->
<behaviors>
<!-- START: to return JSON -->
<endpointBehaviors>
<behavior name="jsonBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
<!-- END: to return JSON -->
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add scheme="http" binding="webHttpBinding"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
並且我有以下使用該服務的控制台應用程序:
Program.cs中
internal class Program
{
private static void Main(string[] args)
{
Login().Wait();
}
private static async Task Login()
{
var client = new AuthenticationServiceClient();
var ok = await client.LoginAsync("User", "Password!", "Console Application");
client.Close();
Console.WriteLine(ok);
}
}
App.config中
<system.serviceModel>
<client>
<endpoint address="http://localhost:62085/AuthenticationService.svc/"
binding="webHttpBinding"
contract="AuthenticationServiceReference.IAuthenticationService"
kind="webHttpEndpoint" />
</client>
</system.serviceModel>
我使用Postman來測試發送以下JSON數據的服務,並且該服務有效:
{"username": "reviewer", "password": "456", "applicationName": "123"}
但是,當我使用控制台應用程序測試服務時,
System.InvalidOperationException:合同'IAuthenticationService'的操作'Login'指定了要序列化的多個請求正文參數,而沒有任何包裝器元素。 沒有包裝器元素,最多可以序列化一個body參數。 刪除多余的正文參數,或將WebGetAttribute / WebInvokeAttribute上的BodyStyle屬性設置為Wrapped。
從IAuthenticationService.cs
代碼中可以看到,我已經將BodyStyle
設置為Wrapped
。 有人可以指導我這里做錯了什么嗎?
請注意以下幾點:
BodyStyle
。 它可能對其他人有所幫助,但對我卻沒有做太多。 Login
和LoginAsync
; 結果是一樣的 這就是您應該如何致電您的服務。
public void DoLogin()
{
string uri = "http://localhost:62085/AuthenticationService.svc/Login";
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request.Method = "POST";
request.ContentType = "text/json";
string data = "{\"username\": \"reviewer\", \"password\": \"456\", \"applicationName\": \"123\"}";
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
byte[] bytes = encoding.GetBytes(data);
request.ContentLength = bytes.Length;
using (Stream requestStream = request.GetRequestStream())
{
// Send the data.
requestStream.Write(bytes, 0, bytes.Length);
}
using (HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(x))
{
using(var responseStream = response.GetResponseStream())
{
using(var reader = new StreamReader(responseStream))
{
//Here you will get response
string loginResponse = reader.ReadToEnd();
}
}
}
}
添加到登錄/登錄異步客戶端合同方法
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)].
因此,您的客戶合同將如下所示:
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="ServiceReference1.IAuthenticationService")]
public interface IAuthenticationService {
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAuthenticationService/Login", ReplyAction="http://tempuri.org/IAuthenticationService/LoginResponse")]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
bool Login(string username, string password, string applicationName);
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAuthenticationService/Login", ReplyAction="http://tempuri.org/IAuthenticationService/LoginResponse")]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
System.Threading.Tasks.Task<bool> LoginAsync(string username, string password, string applicationName);
}
客戶合同是自動生成的。 因此,您應該在每次更新服務引用之后執行此操作。 在此處輸入鏈接說明
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.