如何接受JSON在WCF DataService的? [英] How to accept JSON in a WCF DataService?

查看:121
本文介绍了如何接受JSON在WCF DataService的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解如何使用WCF数据服务(基于EF 4.1)来创建一个RESTful Web服务,将坚持以JSON对象传递实体。



我已经能够创建一个可以接受一组基本数据类型作为参数的GET请求的方法。我不喜欢这样的解决方案,我宁愿与发送的HTTP请求体JSON对象POST请求。



我发现我做不到获得该框架的JSON序列化到一个对象,但我会罚款做手工。



我的问题是,我似乎无法读取POST请求的身体 - 身体应该是JSON有效载荷



下面是一个粗略的裂缝在它的下面。我试过的这几个不同的迭代,似乎无法得到原始JSON出请求体。



有什么想法?一个更好的办法来做到这一点?我只是想张贴一些JSON数据,并对其进行处理。

  [WebInvoke(方法=POST)] 
公共无效SaveMyObj()
{
StreamReader的R =新的StreamReader(HttpContext.Current.Request.InputStream);
串jsonBody = r.ReadToEnd(); // jsonBody是空的!

的JavaScriptSerializer JSS =新的JavaScriptSerializer();
MyObj中O =(MyObj中)jss.Deserialize(jsonBody的typeof(MyObj中));

//现在做验证,业务逻辑和坚持我的对象
}

我的DataService是一个实体框架的DataService扩展

  System.Data.Services.DataService< T> 

如果我尝试添加非原始值作为参数传递给方法,我看到了以下异常跟踪日志:

  System.InvalidOperationException,mscorlib程序,版本= 4.0.0.0,文化=中性公钥= b77a5c561934e089 
虚空SaveMyObj(MyNamespace.MyObj)'有不被支持的服务操作类型'MyNamespace.MyObj'的参数'MyNamespace.MyObj O'。只有原始类型的支持作为参数。


解决方案

添加参数,以你的方法。您还需要在你的WebInvoke一些额外的属性。



下面是一个例子(从内存中,因此它可能是一个小关)

  [WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped,RequestFormat = WebMessageFormat.Json,ResponseFormat = WebMessageFormat.Json,UriTemplate =modifyMyPerson)] 
公共无效修改(人人){

}

通过人类的东西像这样的:

  [DataContract] 
公共类Person {

[数据成员(订购= 0)
公共字符串名字{获得;组; }

}



和JSON这样的发送

 变种人= {姓:安东尼}; 
VAR jsonString = JSON.stringify({人:人});
//使用什么的,我个人使用jQuery
然后发送该字符串后



编辑:这是通过包装的做法。如果没有包装的方法,你会拿出 BodyStyle = ... 和字符串化你只想做JSON JSON.stringify(人)。我只是平时使用的包装方法的情况下,我曾经需要添加额外的参数。



修改有关完整的代码示例



的Global.asax

 使用系统; 
使用System.ServiceModel.Activati​​on;
使用的System.Web;
使用System.Web.Routing;

命名了myNameSpace
{
公共类全球:HttpApplication的
{
保护无效的Application_Start(对象发件人,EventArgs五)
{
RouteTable.Routes.Add(新ServiceRoute(为MyService,新WebServiceHostFactory()的typeof(为MyService)));
}
}
}



Service.cs

 使用系统; 
使用System.ServiceModel;
使用System.ServiceModel.Activati​​on;
使用System.ServiceModel.Web;

命名了myNameSpace
{
[的ServiceContract]
[ServiceBehavior(MaxItemsInObjectGraph = int.MaxValue)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)
公共类的MyService
{
[OperationContract的]
[WebInvoke(UriTemplate =ADDOBJECT,ResponseFormat = WebMessageFormat.Json,BodyStyle = WebMessageBodyStyle.WrappedRequest)]
公无效ADDOBJECT(为MyObject myObject的)
{
// ...
}

[OperationContract的]
[WebInvoke(UriTemplate =updateObject,ResponseFormat = WebMessageFormat.Json,BodyStyle = WebMessageBodyStyle.WrappedRequest)]
公共无效UpdateObject(为MyObject myObject的)
{
// ...
}

[OperationContract的]
[WebInvoke(UriTemplate =DeleteObject的,ResponseFormat = WebMessageFormat.Json,BodyStyle = WebMessageBodyStyle.WrappedRequest)]
公共无效DeleteObject的(GUID myObjectId)
{
/ / ...
}
}
}

和补充这的Web.config

 < system.serviceModel> 
< serviceHostingEnvironment aspNetCompatibilityEnabled =真/>
< /system.serviceModel>


I'm trying to understand how to use WCF Data Services (based on EF 4.1) to create a restful web service that will persist entities passed as JSON objects.

I've been able to create a method that can accept a GET request with a set of primitive data types as arguments. I don't like that solution, I would prefer to send a POST request with a JSON object in the http request body.

I've found that I can't get the framework to serialize the json into an object for me, but i would be fine with doing it manually.

My problem is that I can't seem to read the body of the POST request - the body should be the JSON payload.

Here's a rough crack at it below. I've tried a few different iterations of this and can't seem to get the raw JSON out of the request body.

Any thoughts? A better way to do this? I just want to POST some JSON data and process it.

    [WebInvoke(Method = "POST")]
    public void SaveMyObj()
    {
        StreamReader r = new StreamReader(HttpContext.Current.Request.InputStream);
        string jsonBody = r.ReadToEnd();  // jsonBody is empty!!

        JavaScriptSerializer jss = new JavaScriptSerializer();
        MyObj o = (MyObj)jss.Deserialize(jsonBody, typeof(MyObj));

        // Now do validation, business logic, and persist my object
    }

My DataService is an Entity Framework DataService that extends

System.Data.Services.DataService<T>

If I try adding non-primitive values as parameters to the method, i see the following exception in the trace log:

System.InvalidOperationException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
'Void SaveMyObj(MyNamespace.MyObj)' has a parameter 'MyNamespace.MyObj o' of type 'MyNamespace.MyObj' which is not supported for service operations. Only primitive types are supported as parameters.

解决方案

Add parameters to your method. You'll also want some additional attributes on your WebInvoke.

Here's an example (from memory so it might be a little off)

[WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "modifyMyPerson")]
public void Modify(Person person) {
   ...
}

With person class something like this:

[DataContract]
public class Person {

[DataMember(Order = 0)]
public string FirstName { get; set; }

}

And json sent like this

var person = {FirstName: "Anthony"};
var jsonString = JSON.stringify({person: person});
// Then send this string in post using whatever, I personally use jQuery

EDIT: This is using "wrapped" approach. Without wrapped approach you would take out the BodyStyle = ... and to stringify the JSON you would just do JSON.stringify(person). I just usually use the wrapped methodology in case I ever need to add additional parameters.

EDIT For full code sample

Global.asax

using System;
using System.ServiceModel.Activation;
using System.Web;
using System.Web.Routing;

namespace MyNamespace
{
    public class Global : HttpApplication
    {
        protected void Application_Start(object sender, EventArgs e)
        {
            RouteTable.Routes.Add(new ServiceRoute("myservice", new WebServiceHostFactory(), typeof(MyService)));
        }
    }
}

Service.cs

using System;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;

namespace MyNamespace
{
    [ServiceContract]
    [ServiceBehavior(MaxItemsInObjectGraph = int.MaxValue)]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class MyService
    {
        [OperationContract]
        [WebInvoke(UriTemplate = "addObject", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
        public void AddObject(MyObject myObject)
        {
            // ...
        }

        [OperationContract]
        [WebInvoke(UriTemplate = "updateObject", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
        public void UpdateObject(MyObject myObject)
        {
            // ...
        }

        [OperationContract]
        [WebInvoke(UriTemplate = "deleteObject", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
        public void DeleteObject(Guid myObjectId)
        {
            // ...
        }
    }
}

And add this to Web.config

  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
  </system.serviceModel>

这篇关于如何接受JSON在WCF DataService的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆