mar*_*man 2 rest wcf json wcf-rest
我正在开发一个WCF resful服务,它将基本上从一些移动应用程序中消耗.在POST上我试图发送一个DataContract对象[实际上我必须发送一个对象列表]和另一个单独的id作为字符串.我的问题是,是否可能定义我的函数来接受DataContract对象和单个字符串?
以下是我的代码:接口声明:
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, UriTemplate = "GetDataUsingDataContract/{id}")]
CompositeType GetDataUsingDataContract(string id, CompositeType composite );
}
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
功能的实际定义:
public CompositeType GetDataUsingDataContract(string id, CompositeType composite )
{
if (composite == null)
{
throw new ArgumentNullException("composite");
}
if (composite .BoolValue)
{
composite .StringValue += "- Suffix and the id is"+id;
}
return report;
}
Run Code Online (Sandbox Code Playgroud)
我试图从Fiddler发送的json对象是
{"BoolValue":true,"StringValue":"sdfsdfsf"}
Run Code Online (Sandbox Code Playgroud)
以上是我正在测试服务的小提琴手的快照.经过几次谷歌搜索后,我得到了以下链接,其中客户端实际使用webservice引用获取DataContract类型并序列化为json,然后作为请求体发送.但是为什么我对Fiddler的测试没有成功?
http://dotnetmentors.com/wcf/wcf-rest-service-to-get-or-post-json-data-and-retrieve-json-data-with-datacontract.aspx
任何人都可以建议吗?
web.config如下:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="JSONWebService.Service1" behaviorConfiguration="JSONWebService.Service1Behavior">
<endpoint address="../Service1.svc"
binding="webHttpBinding"
contract="JSONWebService.IService1"
behaviorConfiguration="webBehaviour" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="JSONWebService.Service1Behavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webBehaviour">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
Run Code Online (Sandbox Code Playgroud)
Dom*_*tts 12
要使此方案起作用,您需要做几件事.
首先,在服务合同中,您需要将具有多个参数的方法标记为WebInvoke属性的BodyStyle参数设置为Wrapped,如此示例所示(根据您在http://dotnetmentors.com/链接的示例改编)wcf/wcf-rest-service-to-get-or-post-json-data-and-retrieve-json-data-with-datacontract.aspx):
[OperationContract]
[WebInvoke(UriTemplate = "/PlaceOrder",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json, Method = "POST",
BodyStyle = WebMessageBodyStyle.Wrapped)]
bool PlaceOrder(string id, OrderContract order);
Run Code Online (Sandbox Code Playgroud)
使用此属性参数,您必须将多个Web方法参数包装到客户端中的单个字符串中.以下示例显示了在C#中执行此操作的方法:
var requestdata = new
{
id = order.OrderID,
order = order
};
string data2 = JsonConvert.SerializeObject(requestdata);
Run Code Online (Sandbox Code Playgroud)
请注意,匿名方法中的字段名称与Web方法中的参数名称匹配.
作为参考,它生成的JSON看起来像这样你可以在JSON字符串中看到id和order对象:
{"id":"10560","order":{"OrderID":"10560","OrderDate":"06/09/2013 12:29:04","ShippedDate":"16/09/2013 12:29:04","ShipCountry":"Uganda","OrderTotal":"781"}}
您应该能够使用您的示例在Fiddler中以此格式测试JSON.
扩展答案以处理其他数据类型
使用包含bool和DateTime属性的DataContract:
[DataContract]
public class OrderContract
{
[DataMember]
public string OrderID { get; set; }
[DataMember]
public string OrderDate { get; set; }
[DataMember]
public string ShippedDate { get; set; }
[DataMember]
public string ShipCountry { get; set; }
[DataMember]
public string OrderTotal { get; set; }
[DataMember]
public bool Shipped { get; set; }
[DataMember]
public DateTime DeliveredDate { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是处理DateTime并确保JSON采用WCF RESTful服务可以反序列化的格式.为了实现这一点,我在客户端上使用了这段代码:
OrderContract order = new OrderContract
{
OrderID = "10560",
OrderDate = DateTime.Now.ToString(),
ShippedDate = DateTime.Now.AddDays(10).ToString(),
ShipCountry = "India",
OrderTotal = "781",
Shipped = true,
DeliveredDate = DateTime.Now
};
DataContractJsonSerializer ser =
new DataContractJsonSerializer(typeof(OrderContract));
MemoryStream mem = new MemoryStream();
ser.WriteObject(mem, order);
string data =
Encoding.UTF8.GetString(mem.ToArray(), 0, (int)mem.Length);
var requestdata = new
{
id = order.OrderID,
order = order
};
JsonSerializerSettings microsoftDateFormatSettings = new JsonSerializerSettings
{
DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
};
string data2 = JsonConvert.SerializeObject(requestdata, microsoftDateFormatSettings);
WebClient webClient = new WebClient();
webClient.Headers["Content-type"] = "application/json";
webClient.Encoding = Encoding.UTF8;
webClient.UploadString("http://localhost:61966/OrderService.svc/PlaceOrder", "POST", data2);
Run Code Online (Sandbox Code Playgroud)
请注意JSON Serializer设置 - 这会生成以下JSON:
{"id":"10560","order":{"OrderID":"10560","OrderDate":"10/09/2013 16:15:30","ShippedDate":"20/09/2013 16:15:30","ShipCountry":"India","OrderTotal":"781","Shipped":true,"DeliveredDate":"\/Date(1378826130655+0100)\/"}}
Run Code Online (Sandbox Code Playgroud)