我在WCF上关注了这个视频系列并让演示工作.它涉及构建管理学生评估表单的WCF服务,并实现CRUD操作以对这些评估列表进行操作.我根据本指南稍微修改了我的代码,因此它会将JSON结果返回给浏览器或Fiddler请求.我的目标是通过在Fiddler中构建我自己的请求来弄清楚如何使用该服务,然后使用该格式从移动设备上的应用程序中使用该服务.
我在使用SubmitEvalFiddler 的方法(保存评估)时遇到了麻烦.调用有效,但所有字段Eval都为null(或默认),除了Id在服务本身中设置.
这是我的Eval声明(根据此问题使用属性而不是字段):
[DataContract]
public class Eval //Models an evaluation
{
[DataMember]
public string Id { get; set; }
[DataMember]
public string Submitter { get; set; }
[DataMember]
public string Comment { get; set; }
[DataMember]
public DateTime TimeSubmitted { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
以下是相关部分IEvalService:
[ServiceContract]
public interface IEvalService
{
...
[OperationContract]
[WebInvoke(RequestFormat=WebMessageFormat.Json,
ResponseFormat=WebMessageFormat.Json, UriTemplate = "eval")]
void SubmitEval(Eval eval);
}
Run Code Online (Sandbox Code Playgroud)
而且EvalService:
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
class EvalService : IEvalService
{
...
public void SubmitEval(Eval eval)
{
eval.Id = Guid.NewGuid().ToString();
Console.WriteLine("Received eval");
evals.Add(eval);
}
}
Run Code Online (Sandbox Code Playgroud)
在Fiddler的Request Builder中,我将Method设置为POST,将地址设置为http://localhost:49444/EvalServiceSite/Eval.svc/eval.我将标头添加Content-Type: application/json; charset=utf-8到默认标头.请求正文是:
{"eval":{"Comment":"testComment222","Id":"doesntMatter",
"Submitter":"Tom","TimeSubmitted":"11/10/2011 4:00 PM"}}
Run Code Online (Sandbox Code Playgroud)
我从发送该请求得到的回应是200,但是当我再看看已经保存了Evals,我只是增加了一个具有有效的Id,但Comment和Submitter都为null,并且TimeSubmitted是1/1/0001 12:00:00 AM.
看起来WCF正在获取请求,但没有正确反序列化对象.但如果是这样的话,我不知道为什么它不会引发某种例外.看起来我做得对,或者我错过了什么?
更新:这是App.config中的端点声明:
<endpoint binding="webHttpBinding" behaviorConfiguration="webHttp"
contract="EvalServiceLibrary.IEvalService" />
Run Code Online (Sandbox Code Playgroud)
并且端点行为指的是:
<behavior name="webHttp">
<webHttp defaultOutgoingResponseFormat="Json"/>
</behavior>
Run Code Online (Sandbox Code Playgroud)
WebInvoke属性中的默认主体样式是Bare,这意味着应该在没有包含对象名称的包装器的情况下发送对象:
{"Comment":"testComment222",
"Id":"doesntMatter",
"Submitter":"Tom",
"TimeSubmitted":"11/10/2011 4:00 PM"}
Run Code Online (Sandbox Code Playgroud)
或者您可以将请求正文样式设置为Wrapped,这将使输入需要包装{"eval"...}对象:
[OperationContract]
[WebInvoke(RequestFormat=WebMessageFormat.Json,
ResponseFormat=WebMessageFormat.Json,
UriTemplate = "eval",
BodyStyle = WebMessageBodyStyle.WrappedRequest)] // or .Wrapped
void SubmitEval(Eval eval);
Run Code Online (Sandbox Code Playgroud)
更新:您的代码中存在另一个问题,因为您正在使用DateTime,并且WCF序列化程序对JSON中的日期所期望的格式是这样的\/Date(1234567890)\/.您可以按照MSDN Link中描述的逻辑(对基元的序列化格式进行细粒度控制)更改类以支持您的格式,并在下面的代码中显示.
public class StackOverflow_8086483
{
[DataContract]
public class Eval //Models an evaluation
{
[DataMember]
public string Id { get; set; }
[DataMember]
public string Submitter { get; set; }
[DataMember]
public string Comment { get; set; }
[DataMember(Name = "TimeSubmitted")]
private string timeSubmitted;
public DateTime TimeSubmitted { get; set; }
public override string ToString()
{
return string.Format("Eval[Id={0},Submitter={1},Comment={2},TimeSubmitted={3}]", Id, Submitter, Comment, TimeSubmitted);
}
[OnSerializing]
void OnSerializing(StreamingContext context)
{
this.timeSubmitted = this.TimeSubmitted.ToString("MM/dd/yyyy h:mm tt", CultureInfo.InvariantCulture);
}
[OnDeserialized]
void OnDeserialized(StreamingContext context)
{
DateTime value;
if (DateTime.TryParseExact(this.timeSubmitted, "MM/dd/yyyy h:mm tt", CultureInfo.InvariantCulture, DateTimeStyles.None, out value))
{
this.TimeSubmitted = value;
}
}
}
[ServiceContract]
public interface IEvalService
{
[OperationContract]
[WebInvoke(RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json, UriTemplate = "eval",
BodyStyle = WebMessageBodyStyle.Wrapped)]
void SubmitEval(Eval eval);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
class EvalService : IEvalService
{
public void SubmitEval(Eval eval)
{
Console.WriteLine("Received eval: {0}", eval);
}
}
public static void Test()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
WebServiceHost host = new WebServiceHost(typeof(EvalService), new Uri(baseAddress));
host.Open();
Console.WriteLine("Host opened");
string data = "{\"eval\":{\"Comment\":\"testComment222\",\"Id\":\"doesntMatter\", \"Submitter\":\"Tom\",\"TimeSubmitted\":\"11/10/2011 4:00 PM\"}}";
WebClient c = new WebClient();
c.Headers[HttpRequestHeader.ContentType] = "application/json; charset=utf-8";
c.UploadData(baseAddress + "/eval", Encoding.UTF8.GetBytes(data));
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18159 次 |
| 最近记录: |