spo*_*ots 2 c# rest wcf web-services datacontract
如何获取Web服务方法来访问URI和复杂POST数据中的参数?
我有一个Web服务方法,在URI中有一些参数:
"/api/{something}/{id}"
Run Code Online (Sandbox Code Playgroud)
我还有一个标有DataContract/Member属性的类,我想让webservice方法接受.请注意,我的类包含一个也标有DataContract/Member属性的子类.
[DataContract]
public class MoreData{
[DataMember]
public string SomeString { get; set; }
[DataMember]
public SubClass SubData {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
我的方法声明如下:
[OperationContract]
[WebInvoke( Method = "POST", UriTemplate = "/api/{something}/{id}")]
public MyWebSvcRetObj Update(string something, string id)
Run Code Online (Sandbox Code Playgroud)
我如何让我的Update方法也接受MoreData类?我已经能够编写如下方法:
[OperationContract]
[WebInvoke( Method = "POST")]
public MyWebSvcRetObj Update(MoreData IncomingData)
Run Code Online (Sandbox Code Playgroud)
但只有当URI没有指定任何参数时,URI才会显示
"api/Update"
Run Code Online (Sandbox Code Playgroud)
最终,我希望我的用户能够像:
$.ajax({
url: 'localhost/site/api/things/12345
type: 'POST'
data: {
SomeString: 'I am a string'
SubData: {
//...more data
}
}
});
Run Code Online (Sandbox Code Playgroud)
我已经尝试将Stream作为Update方法中的最后一个参数,但这似乎不适用于具有子类的类,如我给出的示例.它最终具有键/值对,如"SubData [SomeSubDataProp]":"Val".这对我来说似乎不对.我还尝试在Update方法中添加一个MoreData参数作为最后一个参数,但是我得到一个错误,表示它期待一个流(因为它期望原始数据).我正在尝试做什么?或许我会以错误的方式解决这个问题?
UPDATE
正如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 )
Run Code Online (Sandbox Code Playgroud)
客户看起来像:
$.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
}
}
});
Run Code Online (Sandbox Code Playgroud)
你要保持相同的URI两种,GET和POST.
当使用参数/ api/{something}/{id}调用GET方法时,则基于id,它将向客户端返回他/她可以编辑的数据.
编辑完成后,使用POST方法将编辑后的数据发送回服务器,其中URI和ID与GET请求中提到的相同.
如果是这样,那么这是解决方案:
为此,请使用相同的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);
}
Run Code Online (Sandbox Code Playgroud)
现在,应该是JSON的格式.这很容易.在您的MoreData
班级中,覆盖该ToString()
方法.
public override string ToString()
{
JavaScriptSerializer js = new JavaScriptSerializer();
return js.Serialize(this);
}
Run Code Online (Sandbox Code Playgroud)
该JavaScriptSerializer
在可System.Web.Script.Serialization.现在,要检查您的服务将接受哪种JSON格式,请对您的Web服务方法进行虚拟调用,然后点击方法的断点object.ToString()
.
MoreData md = new MoreData();
string jsonString = md.ToString(); // hit break point here.
Run Code Online (Sandbox Code Playgroud)
当您达到断点时,在jsonString
变量中,您将拥有您的服务将接受的json.因此,建议您的客户端以该格式发送JSON.
因此,您可以在MoreData
类中指定复杂类型.
我希望这能帮到您!谢谢