使用URI和Da​​taContract类参数编写webservice方法

时间:2014-02-20 15:37:07

标签: c# web-services wcf rest datacontract

如何获取访问URI和复杂POST数据中的参数的Web服务方法?

我有一个Web服务方法,在URI中包含一些参数:

"/api/{something}/{id}"

我还有一个标有DataContract / Member属性的类,我想让webservice方法接受。请注意,我的类包含一个也标有DataContract / Member属性的子类。

[DataContract]
public class MoreData{
    [DataMember]
    public string SomeString { get; set; }

    [DataMember]
    public SubClass SubData {get; set;}
}

我的方法声明如下:

[OperationContract]
[WebInvoke( Method = "POST", UriTemplate = "/api/{something}/{id}")]
public MyWebSvcRetObj Update(string something, string id)

如何让我的Update方法也接受MoreData类?我已经能够编写如下方法:

[OperationContract]
[WebInvoke( Method = "POST")]
public MyWebSvcRetObj Update(MoreData IncomingData)

但仅当URI没有指定任何参数时,URI看起来像

"api/Update"

最终我希望我的用户能够做到:

$.ajax({
    url: 'localhost/site/api/things/12345
    type: 'POST'
    data: {
        SomeString: 'I am a string'
        SubData: {
           //...more data
        }
    }
});

我已经尝试将Stream作为Update方法中的最后一个参数,但这似乎不适用于具有子类的类,如我给出的示例。它最终具有键/值对,如“SubData [SomeSubDataProp]”:“Val”。这对我来说似乎不对。我也尝试在Update方法中添加一个MoreData参数作为最后一个参数,但是我得到一个错误,表示它期待一个流(因为它期望原始数据)。我正在尝试做什么?或许我会以错误的方式解决这个问题?

更新

正如Faizan Mubasher所写,如果我的网络方法如下,我的用户将能够发送帖子数据:

[OperationContract]
    [WebInvoke( Method = "POST", 
        UriTemplate = "/v1/{something}/{id}",
        RequestFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Bare
    )]
    [Description( "Update " )]
    public void Update( MoreData Incoming, string something, string id )

客户端看起来像:

$.ajax({
    type: 'POST',
    url: 'http://localhost/app/api/something/12345',
    contentType: 'application/json',                  //need to specify type
    data: JSON.stringify({                            //note the "stringify" call
        SomeString: 'hello, world',
        SubClass: {
            SubStr: 'hello, again',
            SubInt: 98765
        }
    }
});

2 个答案:

答案 0 :(得分:5)

您希望为 GET POST 保留相同的 URI

  1. 使用参数 / api / {something} / {id} 调用 GET 方法时,则基于 id ,它会将数据返回给客户,他/她可以编辑。

  2. 编辑完成后,使用 POST 方法将编辑后的数据发送回服务器,其中包含相同的 URI Id GET 请求。

  3. 如果是这样,那么这就是解决方案:

    为此,请使用相同的 UriTemplate 创建两个方法,但名称不同。

    [ServiceContract]
    public interface IMyWebSvc
    {
    
        [OperationContract]
        [WebGet(UriTemplate = "/api/{something}/{id}",
            ResponseFormat = WebMessageFormat.Json,
            BodyStyle = WebMessageBodyStyle.Bare)]
        MyWebSvcRetObj GetData(string something, string id);
    
        [OperationContract]
        [WebInvoke(Method = "POST", UriTemplate = "/api/{something}/{id}",
            RequestFormat = WebMessageFormat.Json,    
            BodyStyle = WebMessageBodyStyle.Bare)]
        string Update(MoreData IncomingData, string something, string id);       
    }
    

    现在,JSON的格式应该是什么。这很容易。在MoreData课程中,覆盖 ToString()方法。

    public override string ToString()
    {
        JavaScriptSerializer js = new JavaScriptSerializer();
        return js.Serialize(this);
    }
    

    System.Web.Script.Serialization 中提供了JavaScriptSerializer。现在,要检查您的服务将接受哪种JSON格式,请对您的Web服务方法进行虚拟调用,然后点击object.ToString()方法的断点。

    MoreData md = new MoreData();
    string jsonString = md.ToString(); // hit break point here.
    

    当您达到断点时,在jsonString变量中,您将拥有您的服务将接受的json。因此,建议您的客户端以该格式发送JSON。

    因此,您可以在MoreData类中指定复杂类型。

    我希望这会对你有所帮助!感谢

答案 1 :(得分:0)

您似乎将JSON数据发布到强类型的Web服务方法。

这与此主题有些相似:How to pass strong-typed model as data param to jquery ajax post?

一种解决方案是接受Json对象(您提到的键值对)并反序列化为MoreData类型。