この記事を参考にWCFを使ってRESTFulインターフェースを書いてみます。サーバー側のコードは次のようになります: ======これはインターフェースです =======
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web;
namespace RESTFulDaemon
{
[ServiceContract]
public interface IRestSerivce
{
//POST operation
[OperationContract]
[WebInvoke(UriTemplate = "", Method = "POST")]
Person CreatePerson(Person createPerson);
//Get Operation
[OperationContract]
[WebGet(UriTemplate = "")]
List<Person> GetAllPerson();
[OperationContract]
[WebGet(UriTemplate = "{id}")]
Person GetAPerson(string id);
//PUT Operation
[OperationContract]
[WebInvoke(UriTemplate = "{id}", Method = "PUT")]
Person UpdatePerson(string id, Person updatePerson);
//DELETE Operation
[OperationContract]
[WebInvoke(UriTemplate = "{id}", Method = "DELETE")]
void DeletePerson(string id);
}
}
=======これがサービスです ===================
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Activation;
using System.ServiceModel;
namespace RESTFulDaemon
{
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class RESTService:IRestSerivce
{
List<Person> persons = new List<Person>();
public Person CreatePerson(Person person)
{
persons.Add(person);
return person;
}
public List<Person> GetAllPerson()
{
return persons.ToList();
}
public Person GetAPerson(string id)
{
return persons.FirstOrDefault(e => e.ID.Equals(id));
}
public Person UpdatePerson(string id, Person updatePerson)
{
Person p = persons.FirstOrDefault(e => e.ID.Equals(id));
p.Name = updatePerson.Name;
p.Age = updatePerson.Age;
return p;
}
public void DeletePerson(string id)
{
persons.RemoveAll(e => e.ID.Equals(id));
}
}
}
=========以下はクライアントコードです===============
private void btnCreate_Click(object sender, RoutedEventArgs e)
{
//Client entity
Person p = new Person();
p.ID = "1";
p.Name = "scy";
p.Age = "25";
p.Address = "China HeNan";
HttpWebRequest request = WebRequest.Create("http://localhost:11126/RESTService/") as HttpWebRequest;
request.KeepAlive = false;
request.Method = "POST";
StringWriter sw = new StringWriter();
XmlSerializer xs = new XmlSerializer(p.GetType());
xs.Serialize(sw,(object)p);
string result = sw.ToString();
//generate xml that required
result = result.Replace("<?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n",string.Empty);
Regex regex = new Regex("<Person.*?>");
Match m = regex.Match(result);
if (m.Success)
{
result = result.Replace(m.Value,"<Person xmlns=\"http://schemas.datacontract.org/2004/07/RESTFulDaemon\">");
}
byte[] buffer = Encoding.Default.GetBytes(result);
request.ContentLength = buffer.Length;
request.ContentType = "text/xml";
Stream PostData = request.GetRequestStream();
PostData.Write(buffer, 0, buffer.Length);
PostData.Close();
HttpWebResponse resp = request.GetResponse() as HttpWebResponse;
StreamReader loResponseStream = new StreamReader(resp.GetResponseStream(), Encoding.Default);
string Response = loResponseStream.ReadToEnd();
MessageBox.Show(Response);
loResponseStream.Close();
resp.Close();
}
問題は、ボタンをクリックするたびに、次のようなメッセージが表示されることです。
<Person xmlns="http://schemas.datacontract.org/2004/07/RESTFulDaemon">
<ID>1</ID>
<Name>scy</Name>
<Age>25</Age>
<Address>China HeNan</Address>
</Person>
しかし、実際には次のような結果が得られました:
<Person xmlns="http://schemas.datacontract.org/2004/07/RESTFulDaemon">
<Address i:nil="true" />
<Age i:nil="true" />
<ID>1</ID>
<Name>scy</Name>
</Person>
誰かアドバイスをください。どうも。
編集: RESTService クラスに対してデバッグを実行したところ、CreatePerson 関数にデバッグするたびに、Adress と Age の値が null の person エンティティが得られることがわかりました。クライアントストリームの書き込みに何か問題があるのではないかと思います。