Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在WCF数据服务中接受JSON?_C#_Json_Wcf Data Services_Ef4 Code Only - Fatal编程技术网

C# 如何在WCF数据服务中接受JSON?

C# 如何在WCF数据服务中接受JSON?,c#,json,wcf-data-services,ef4-code-only,C#,Json,Wcf Data Services,Ef4 Code Only,我试图理解如何使用WCF数据服务(基于EF4.1)创建一个restful web服务,该服务将持久化作为JSON对象传递的实体 我已经能够创建一个方法,该方法可以接受GET请求,并使用一组基本数据类型作为参数。我不喜欢这种解决方案,我更喜欢在http请求体中发送带有JSON对象的POST请求 我发现我无法让框架为我将json序列化为一个对象,但我可以手动完成 我的问题是,我似乎无法读取POST请求的主体——主体应该是JSON负载 下面有一条粗糙的裂缝。我尝试了几个不同的迭代,但似乎无法从请求体中

我试图理解如何使用WCF数据服务(基于EF4.1)创建一个restful web服务,该服务将持久化作为JSON对象传递的实体

我已经能够创建一个方法,该方法可以接受GET请求,并使用一组基本数据类型作为参数。我不喜欢这种解决方案,我更喜欢在http请求体中发送带有JSON对象的POST请求

我发现我无法让框架为我将json序列化为一个对象,但我可以手动完成

我的问题是,我似乎无法读取POST请求的主体——主体应该是JSON负载

下面有一条粗糙的裂缝。我尝试了几个不同的迭代,但似乎无法从请求体中获取原始JSON

有什么想法吗?有更好的方法吗?我只想发布一些JSON数据并对其进行处理

    [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是一个实体框架DataService,它扩展了

System.Data.Services.DataService<T>

向方法中添加参数。您还需要WebInvoke上的一些附加属性

下面是一个示例(来自内存,因此可能有点不正确)

对于person类,如下所示:

[DataContract]
public class Person {

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

}
json是这样发送的

var person = {FirstName: "Anthony"};
var jsonString = JSON.stringify({person: person});
// Then send this string in post using whatever, I personally use jQuery
编辑:这是使用“包装”方法。如果没有包装方法,您将去掉
BodyStyle=…
,而要对JSON进行字符串化,您只需执行
JSON.stringify(person)
。我通常只使用包装方法,以防需要添加额外的参数

编辑完整代码样本

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)
        {
            // ...
        }
    }
}
并将其添加到
Web.config

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


My service似乎不允许非基本类型作为参数。我正在使用一个实体框架DataService(扩展System.Data.Services.DataService)。如果参数中有任何类型的非原语,我会得到一个异常:
code
。。。具有类型为“MyNamespace.MyObj”的参数“MyNamespace.MyObj bv”,服务操作不支持该参数。只支持原语类型作为参数。
code
这是一个不幸的缺点。。。如果我是你,我会放弃
数据服务
,除非你从中获得其他好处。我将编辑我的文章,以获得一个完整的代码示例,我使用的代码非常适合我。这是一个很好的建议,我不确定这是否是DataService的一个限制。据我所知,我使用该数据服务自动执行REST CRUD操作(仅限get req)。在这种情况下,我不需要自动CRUD,因为我需要在持久化之前执行一些验证和业务逻辑。我会尝试你的方法,然后在这里更新。这对我很有用。我的问题肯定是由于扩展了
DataService
,令人失望的是它不支持服务方法调用的对象参数。@codemonkey这实际上是OData标准的限制,而不是WCF数据服务本身的限制。你可以攻击WCF数据服务来获取post数据。Glenn Gailey在这篇名为“将数据上传到服务操作”的相关博文中简要提到了这一点:尽管如此,不建议使用这种黑客,因此应序列化复杂类型(博文中也提到)。
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)
        {
            // ...
        }
    }
}
  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
  </system.serviceModel>