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

标签 c# json wcf-data-services ef4-code-only

我正在尝试了解如何使用 WCF 数据服务(基于 EF 4.1)创建一个稳定的 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
    }

我的数据服务是一个扩展的 Entity Framework 数据服务

System.Data.Services.DataService<T>

如果我尝试将非原始值作为参数添加到方法中,我会在跟踪日志中看到以下异常:

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.

最佳答案

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

这是一个例子(凭内存所以可能有点偏差)

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

像这样的 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.stringify(person) 的 JSON。我只是通常使用包装方法,以防我需要添加额外的参数。

编辑完整代码示例

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>

关于c# - 如何在 WCF 数据服务中接受 JSON?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6917380/

相关文章:

c# - 内存困惑

c# - 适用于 Windows 和 MS-Access 数据库和 Jet.OLEDB.4.0 的 Docker

c# - 如何使用 DotNumerics 解决线性规划问题?

c# - JSON 到 XML 类转换

android - 使用产品风格实现 Google Analytics V4

android - wcf 数据服务中的 android 推送通知

wcf - Silverlight 中 ADO.NET 数据服务和 WCF 服务之间的重用类型

c# - HtmlWindow.Error 未捕获脚本错误 .NET

php - 如何将 BLOB 与 JSON 和 PHP 一起使用?

wcf - 如何处理从WCF数据服务(OData)返回的json DateTime