我是wcf restful service的新手。我找不到问题,为什么我的wcf宁静服务给出“错误的请求”。我使用.NET 4.0。
我的服务是:
[OperationContract(Name="Add")]
[WebInvoke(UriTemplate = "test/", Method = "POST",
ResponseFormat=WebMessageFormat.Json,
RequestFormat=WebMessageFormat.Json )]
public int Add(Number n1)
{
res = Convert.ToInt32(n1.Number1) + Convert.ToInt32(n1.Number2);
return res;
}
数据是..
[Serializable]
public class Number
{
public int Number1 { get; set; }
public int Number2 { get; set; }
}
当我从fiddler打电话时,它返回'HTTP / 1.1 400 Bad Request'
我的小提琴请求标题是:
User-Agent: Fiddler
Host: localhost:4217
Content-Type: application/json; charset=utf-8
请求正文是:
{"Number1":"7","Number2":"7"}
响应标题为:
HTTP/1.1 400 Bad Request
Server: ASP.NET Development Server/10.0.0.0
Date: Sun, 14 Aug 2011 18:10:21 GMT
X-AspNet-Version: 4.0.30319
Content-Length: 5450
Cache-Control: private
Content-Type: text/html
Connection: Close
但如果我通过C#客户端程序调用此服务就可以了。
我的客户代码是:
uri = "http://localhost:4217/Service1.svc/";
Number obj = new Number() { Number1 = 7, Number2 = 7 };
using (HttpResponseMessage response = new HttpClient().Post(uri+"test/",
HttpContentExtensions.CreateDataContract(obj)))
{
string res = response.Content.ReadAsString();
return res.ToString();
}
请帮帮我........
感谢。
答案 0 :(得分:8)
您将发现代码问题的方法是服务器上的enable tracing,它会解释问题。我用你的代码写了一个简单的测试,它有一个类似的错误(400),并且跟踪有以下错误:
The data contract type 'WcfForums.StackOverflow_7058942+Number' cannot be
deserialized because the required data members '<Number1>k__BackingField,
<Number2>k__BackingField' were not found.
标有[Serializable]
的数据类型序列化对象中的所有字段,而非属性。通过注释掉该属性,代码实际上运行良好(该类型然后属于“POCO”(Plain Old Clr Object)规则,该规则序列化所有公共字段和属性。
public class StackOverflow_7058942
{
//[Serializable]
public class Number
{
public int Number1 { get; set; }
public int Number2 { get; set; }
}
[ServiceContract]
public class Service
{
[OperationContract(Name = "Add")]
[WebInvoke(UriTemplate = "test/", Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
public int Add(Number n1)
{
int res = Convert.ToInt32(n1.Number1) + Convert.ToInt32(n1.Number2);
return res;
}
}
public static void Test()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
host.AddServiceEndpoint(typeof(Service), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());
host.Open();
Console.WriteLine("Host opened");
WebClient c = new WebClient();
c.Headers[HttpRequestHeader.ContentType] = "application/json; charset=utf-8";
c.Encoding = Encoding.UTF8;
Console.WriteLine(c.UploadString(baseAddress + "/test/", "{\"Number1\":\"7\",\"Number2\":\"7\"}"));
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}
答案 1 :(得分:2)
您做错的一件事是请求对象的格式。张它到:
{ n1: { "Number1":"7","Number2":"7"} }
参数名称是传递给wcf json端点的json对象的根属性名称。
我在git上有一个sample wcf service。除此之外,它有一个json端点,在Default.asmx我用jquery来调用它。我建议你构建一个类似的网页(托管在与WCF服务相同的网站上),通过jquery调用你的json服务,并在fiddler运行时测试服务以获取样本请求。这比自己构造请求更容易,更不容易出错,因为jquery会处理标题中的大量细节。
用于调用我的echo服务的示例jquery ajax代码,您可以根据自己的服务进行调整,如下所示:
$("#btnEchoString").click(function () {
var request = $("#request");
var response = $("#response");
$.ajax({
url: 'EchoService.svc/JSON/Echo',
type: "POST",
contentType: "application/json; charset=utf-8",
data: JSON.stringify({ request: request.val() }),
dataType: "json",
success: function (data) {
response.val(data.d);
},
error: function (request, status, error) {
//TODO: do something here
}
});
});