当前位置: 首页 > 面试题库 >

如何在WCF DataService中接受JSON?

薛弘壮
2023-03-14
问题内容

我试图了解如何使用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
    }

我的数据服务是一个扩展的实体框架数据服务

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) {
   ...
}

对于人员类,如下所示:

[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)。如果需要添加其他参数,我通常只使用包装方法。

编辑完整代码示例

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>


 类似资料:
  • Appium v1.6.4-beta Xcode 8.2 macOs Sierra 10.12 我想自动保存照片在我的设备。但是第一次我必须给予许可。我使用了"接受警报",但不能接受允许访问照片库的警报。当我执行测试时,它以绿色显示测试通过,但是这个弹出窗口仍然出现在视图中,照片没有保存。 这是我的剧本 还使用了能力, 这是我想允许的 如何接受此警报?我试过使用xpath sa,但没有成功

  • 问题内容: 因此,几天前我开始学习Java并遇到了一个问题。对于下一个表达式: 不被允许。但是,在中,我们可以使用类似: 由于不允许将整数隐式地分配给字符串,因此上述表达式为何起作用?任何人都可以给出详细的解释吗?我也想知道我们什么时候可以使用这种隐式事物,什么时候不能使用。 问题答案: PrintStream 有很多重载方法:

  • 本文向大家介绍如何限制UITextField在Swift中只接受数字?,包括了如何限制UITextField在Swift中只接受数字?的使用技巧和注意事项,需要的朋友参考一下 在iOS应用中,有时我们需要将文本字段限制为仅将数字作为输入,这可以通过多种方式完成,下面让我们来看一些。 方法1:从情节提要中更改文本字段类型。 选择要限制为数字输入的文本字段。 转到其属性检查器。 选择键盘类型,然后从中

  • 我正在使用ThinkTecture.IdentityModel nuget包为MVC Web应用程序中的WebAPI控制器启用CORS。目前,我只担心文章,但让我知道任何问题与其他动词。这在运行IIS Express服务器时有效。 在处理AppHarbor部署时,它不起作用。nginx似乎不会将选项请求传递给我的代码。还需要什么才能让它在Appharbor上运行? 选项$PATH HTTP/1.1

  • 我怎么能做文本字段只接受字母"N或E"在Java?不接受数字和其他字符。 我试过这个,这个对maxValue有用。但我需要文本字段只接受“N”和“E”字符。那么我该怎么做呢?