2011-08-02 7 views
4

저는 EF 4.1에 기반한 WCF Data Services를 사용하여 JSON 객체로 전달 된 엔티티를 유지할 수있는 편안한 웹 서비스를 만드는 방법을 이해하려고합니다.WCF DataService에서 JSON을 허용하는 방법?

원시 데이터 형식 집합을 인수로 사용하여 GET 요청을 받아 들일 수있는 메서드를 만들 수있었습니다. 그 해결책이 마음에 들지 않아, HTTP 요청 본문에 JSON 객체가있는 POST 요청을 보내고 싶습니다.

json을 개체로 serialize하는 프레임 워크를 얻을 수 없다는 것을 알았지 만 수동으로 수행하는 것이 좋습니다.

제 문제는 POST 요청의 본문을 읽을 수없는 것입니다. 본문은 JSON 페이로드 여야합니다.

여기 아래에 대략적인 균열이 있습니다. 이것에 대한 몇 가지 반복을 시도했지만 요청 본문에서 원시 JSON을 가져올 수 없습니다.

의견이 있으십니까? 이 작업을 수행하는 더 좋은 방법은? 난 그냥 몇 가지 JSON 데이터를 POST하고 처리하고 싶습니다.

[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 
    } 

내 DataService의는

System.Data.Services.DataService<T> 

나는 방법에 매개 변수로 비 원시 값을 추가하려고하면

을 확장하는 엔티티 프레임 워크 DataService에, 나는 추적 로그에 다음과 같은 예외를 참조하십시오

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. 

답변

8

매개 변수를 메서드에 추가하십시오. 또한 WebInvoke에 몇 가지 추가 속성이 필요합니다.

[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 
같이 보내이 같은 사람 클래스 뭔가

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

(조금을 할 수 있도록 메모리에서) 여기

는 예를의

편집 : 이것은 "랩핑 된"방식을 사용하고 있습니다. 래핑 된 접근 방식을 사용하지 않으면 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> 
이 추가
+0

내 서비스가 비 기본 유형을 매개 변수로 허용하지 않는 것 같습니다. Entity Framework DataService (System.Data.Services.DataService를 확장합니다. )를 사용하고 있습니다. 만약 내가 어떤 종류의 프리미티브가 아닌 프리미티브를 가지고 있다면 :'code' ...서비스 조작에 지원되지 않는 'MyNamespace.MyObj'유형의 매개 변수 'MyNamespace.MyObj bv'가 있습니다. 오직 원시 타입 만이 매개 변수로 지원됩니다.'code' – codemonkey

+1

그건 불행한 결점입니다 ... 만약 내가 당신이라면, 당신이 다른 어떤 이점을 얻지 못한다면'DataService '을 드롭 할 것입니다. 나는 나를 위해 훌륭하게 작동하는 것을 사용하는 것에 대한 전체 코드 샘플을 위해 나의 포스트를 편집 할 것이다. –

+0

좋은 제안, 그것이 DataService 의 제한 사항인지 확실하지 않았습니다. 내가 알기로는 DataService를 사용하여 자동 REST CRUD 작업을 수행한다 (GET req에만 해당). 이 경우, 일부 유효성 검사와 비즈니스 로직을 지속하기 전에 수행해야하므로 자동 CRUD는 필요하지 않습니다. 나는 당신의 접근법을 시도 할 것이고, 여기에서 갱신 할 것이다. – codemonkey

관련 문제