Asp.net mvc 在.NETMVC3中使用RESTWeb服务
我正在开发一个.NET4MVC3应用程序。我试图遵循领域驱动的设计范式。现在,我的应用程序分为两部分,一部分是域,另一部分是用于web的MVC代码。我希望得到一些帮助,以确定在这个结构中应该在何处使用RESTful web服务 这个特定的项目使用RESTfulWeb服务来检索和持久化数据。在我的域中,我有两个实体“Customer”和“User”,它们与同名的web服务配对。e、 g.URL/客户和URL/用户。每个web服务接受一些参数,然后以XML格式返回适当的数据列表。我需要以(POST、GET、PUT和DELETE)的形式实现基本的CRUD功能。鉴于此,我有两个主要问题 1.)我应该创建什么类型的对象来使用这些web服务?我的直觉是创建一个定义CRUD操作的ICCustomerService接口,然后以使用HTTPWebConnection(或扩展它?)的类的形式创建该接口的实现。有没有更好的方法来使用RESTful web服务?这种类型的类应该是静态的吗 2.)此服务代码应该放在哪里?同样,我的直觉告诉我,除了代码中的域和WebUI部分之外,我还需要第三个服务部分,其中包含这些web服务客户端的接口和实现,但是由于web服务返回的是我域中的客户和用户实体的XML表示,这些服务不会真正从域中解耦 提前感谢,, 格雷格 编辑 在从事各种项目一段时间后,我发现了一种在MVC中处理RESTWeb服务的好方法 首先,我创建表示我将使用的各种web服务的实体。每个实体使用XML属性将属性与XML元素匹配。下面是一个简单的例子,假设一个web服务返回关于人们及其衬衫的信息(这很愚蠢,但我能马上想出最好的方法) 假设我从web服务获取一个Person对象。这里是XMLAsp.net mvc 在.NETMVC3中使用RESTWeb服务,asp.net-mvc,rest,.net-4.0,dns,domain-driven-design,Asp.net Mvc,Rest,.net 4.0,Dns,Domain Driven Design,我正在开发一个.NET4MVC3应用程序。我试图遵循领域驱动的设计范式。现在,我的应用程序分为两部分,一部分是域,另一部分是用于web的MVC代码。我希望得到一些帮助,以确定在这个结构中应该在何处使用RESTful web服务 这个特定的项目使用RESTfulWeb服务来检索和持久化数据。在我的域中,我有两个实体“Customer”和“User”,它们与同名的web服务配对。e、 g.URL/客户和URL/用户。每个web服务接受一些参数,然后以XML格式返回适当的数据列表。我需要以(POST、
<result>
<resultCount>1</resultCount>
<person>
<personName>Tom</personName>
<shirt>
<shirtColor>red</shirtColor>
<shirtType>sweater</shirtType>
</shirt>
</person>
</result>
然后,我们可以使用XmlSerializer将对象转换为XML,并将XML转换为对象。这是一个我修改过的类。我很抱歉,因为我不记得原始来源。(本课程可能有很大的改进空间)
对象序列化程序
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;
using System.Xml.Serialization;
using System;
using System.Xml.Linq;
public static class ObjectSerializer
{
/// <summary>
/// To convert a Byte Array of Unicode values (UTF-8 encoded) to a complete String.
/// </summary>
/// <param name="characters">Unicode Byte Array to be converted to String</param>
/// <returns>String converted from Unicode Byte Array</returns>
private static string UTF8ByteArrayToString(byte[] characters)
{
UTF8Encoding encoding = new UTF8Encoding();
string constructedString = encoding.GetString(characters);
return (constructedString);
}
/// <summary>
/// Converts the String to UTF8 Byte array and is used in De serialization
/// </summary>
/// <param name="pXmlString"></param>
/// <returns></returns>
private static Byte[] StringToUTF8ByteArray(string pXmlString)
{
UTF8Encoding encoding = new UTF8Encoding();
byte[] byteArray = encoding.GetBytes(pXmlString);
return byteArray;
}
/// <summary>
/// Serialize an object into an XML string
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static string SerializeObject<T>(T obj)
{
try
{
XDocument xml;
using (MemoryStream stream = new MemoryStream())
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlSerializer serializer = new XmlSerializer(typeof(T));
serializer.Serialize(stream, obj, ns);
stream.Close();
byte[] buffer = stream.ToArray();
UTF8Encoding encoding = new UTF8Encoding();
string stringXml = encoding.GetString(buffer);
xml = XDocument.Parse(stringXml);
xml.Declaration = null;
return xml.ToString();
}
}
catch
{
return string.Empty;
}
}
/// <summary>
/// Reconstruct an object from an XML string
/// </summary>
/// <param name="xml"></param>
/// <returns></returns>
public static T DeserializeObject<T>(string xml)
{
XmlSerializer xs = new XmlSerializer(typeof(T));
MemoryStream memoryStream = new MemoryStream(StringToUTF8ByteArray(xml));
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
return (T)xs.Deserialize(memoryStream);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Test.Entities;
using Test.Infrastructure;
using System.Net;
using System.Text;
namespace Test.Controllers
{
public class PeopleController
{
private PersonRepository _personRepository;
public PeopleController()
{
_personRepository = new PersonRepository();
}
public List<Person> List()
{
return _personRepository.GetPeople().ToList<Person>();
}
}
}
使用System.Collections.Generic;
使用系统文本;
使用System.Xml;
使用System.IO;
使用System.Xml.Serialization;
使用制度;
使用System.Xml.Linq;
公共静态类ObjectSerializer
{
///
///将Unicode值(UTF-8编码)的字节数组转换为完整字符串。
///
///要转换为字符串的Unicode字节数组
///从Unicode字节数组转换的字符串
专用静态字符串UTF8ByteArrayToString(字节[]个字符)
{
UTF8Encoding=新的UTF8Encoding();
string constructedString=encoding.GetString(字符);
返回(构造字符串);
}
///
///将字符串转换为UTF8字节数组,并用于反序列化
///
///
///
专用静态字节[]StringToUTF8ByteArray(字符串pXmlString)
{
UTF8Encoding=新的UTF8Encoding();
byte[]byteArray=encoding.GetBytes(pXmlString);
乘火车返回;
}
///
///将对象序列化为XML字符串
///
///
///
///
公共静态字符串序列化对象(T obj)
{
尝试
{
xdocumentxml;
使用(MemoryStream stream=new MemoryStream())
{
XmlSerializerNamespaces ns=新的XmlSerializerNamespaces();
加上(“,”);
XmlSerializer serializer=新的XmlSerializer(typeof(T));
序列化(流、对象、ns);
stream.Close();
字节[]缓冲区=stream.ToArray();
UTF8Encoding=新的UTF8Encoding();
string stringXml=encoding.GetString(缓冲区);
xml=XDocument.Parse(stringXml);
xml.Declaration=null;
返回xml.ToString();
}
}
抓住
{
返回字符串。空;
}
}
///
///从XML字符串重构对象
///
///
///
公共静态T反序列化对象(字符串xml)
{
XmlSerializer xs=新的XmlSerializer(typeof(T));
MemoryStream MemoryStream=新的MemoryStream(StringToUTF8ByteArray(xml));
XmlTextWriter XmlTextWriter=新的XmlTextWriter(memoryStream,Encoding.UTF8);
返回(T)xs.反序列化(memoryStream);
}
}
然后,创建一个通用服务来处理HTTP操作。我使用GET和POST。这是我的班级
HttpService
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Xml.Linq;
namespace Test.Infrastructure
{
public class HttpService
{
public HttpService()
{
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(AcceptCertificate);
}
public XDocument Post(Uri host, string path, Dictionary<string, string> headers, string payload, NetworkCredential credential)
{
try
{
Uri url = new Uri(host.Url, path);
MvcHtmlString encodedPayload = MvcHtmlString.Create(payload);
UTF8Encoding encoding = new UTF8Encoding();
byte[] data = encoding.GetBytes(encodedPayload.ToHtmlString());
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "POST";
request.Credentials = credential;
request.ContentLength = data.Length;
request.KeepAlive = false;
request.ContentType = "application/xml";
MvcHtmlString htmlString1;
MvcHtmlString htmlString2;
foreach (KeyValuePair<string, string> header in headers)
{
htmlString1 = MvcHtmlString.Create(header.Key);
htmlString2 = MvcHtmlString.Create(header.Value);
request.Headers.Add(htmlString1.ToHtmlString(), htmlString2.ToHtmlString());
}
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(data, 0, data.Length);
requestStream.Close();
}
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
using (Stream responseStream = response.GetResponseStream())
{
if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.Created)
{
throw new HttpException((int)response.StatusCode, response.StatusDescription);
}
XDocument xmlDoc = XDocument.Load(responseStream);
responseStream.Close();
response.Close();
return xmlDoc;
}
}
catch (Exception ex)
{
throw;
}
}
public XDocument Get(Uri host, string path, Dictionary<string, string> parameters, NetworkCredential credential)
{
try
{
Uri url;
StringBuilder parameterString = new StringBuilder();
if (parameters == null || parameters.Count <= 0)
{
parameterString.Clear();
} else {
parameterString.Append("?");
foreach (KeyValuePair<string, string> parameter in parameters)
{
parameterString.Append(parameter.Key + "=" + parameter.Value + "&");
}
}
url = new Uri(host.Url, path + parameterString.ToString().TrimEnd(new char[] { '&' }));
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Credentials = credential;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
{
throw new HttpException((int)response.StatusCode, response.StatusDescription);
}
XDocument xmlDoc = XDocument.Load(response.GetResponseStream());
return xmlDoc;
}
}
catch (Exception ex)
{
throw;
}
}
/*
I use this class for internal web services. For external web services, you'll want
to put some logic in here to determine whether or not you should accept a certificate
or not if the domain name in the cert doesn't match the url you are accessing.
*/
private static bool AcceptCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true;
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
Net系统;
使用System.Net.Security;
使用System.Security.Cryptography.X509证书;
使用系统文本;
使用System.Web;
使用System.Web.Mvc;
使用System.Xml.Linq;
命名空间测试.基础结构
{
公共类HttpService
{
公共HttpService()
{
ServicePointManager.ServerCertificateValidationCallback+=新的RemoteCertificateValidationCallback(AcceptCertificate);
}
公共XDocument Post(Uri主机、字符串路径、字典头、字符串负载、网络凭据)
{
尝试
{
Uri url=新的Uri(host.url,路径);
MvcHtmlString encodedPayload=MvcHtmlString.Create(有效载荷);
UTF8Encoding=新的UTF8Encoding();
byte[]data=encoding.GetBytes(encodedPayload.ToHtmlString());
HttpWebRequest request=WebRequest.Create(url)为HttpWe
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Xml.Linq;
namespace Test.Infrastructure
{
public class HttpService
{
public HttpService()
{
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(AcceptCertificate);
}
public XDocument Post(Uri host, string path, Dictionary<string, string> headers, string payload, NetworkCredential credential)
{
try
{
Uri url = new Uri(host.Url, path);
MvcHtmlString encodedPayload = MvcHtmlString.Create(payload);
UTF8Encoding encoding = new UTF8Encoding();
byte[] data = encoding.GetBytes(encodedPayload.ToHtmlString());
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "POST";
request.Credentials = credential;
request.ContentLength = data.Length;
request.KeepAlive = false;
request.ContentType = "application/xml";
MvcHtmlString htmlString1;
MvcHtmlString htmlString2;
foreach (KeyValuePair<string, string> header in headers)
{
htmlString1 = MvcHtmlString.Create(header.Key);
htmlString2 = MvcHtmlString.Create(header.Value);
request.Headers.Add(htmlString1.ToHtmlString(), htmlString2.ToHtmlString());
}
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(data, 0, data.Length);
requestStream.Close();
}
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
using (Stream responseStream = response.GetResponseStream())
{
if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.Created)
{
throw new HttpException((int)response.StatusCode, response.StatusDescription);
}
XDocument xmlDoc = XDocument.Load(responseStream);
responseStream.Close();
response.Close();
return xmlDoc;
}
}
catch (Exception ex)
{
throw;
}
}
public XDocument Get(Uri host, string path, Dictionary<string, string> parameters, NetworkCredential credential)
{
try
{
Uri url;
StringBuilder parameterString = new StringBuilder();
if (parameters == null || parameters.Count <= 0)
{
parameterString.Clear();
} else {
parameterString.Append("?");
foreach (KeyValuePair<string, string> parameter in parameters)
{
parameterString.Append(parameter.Key + "=" + parameter.Value + "&");
}
}
url = new Uri(host.Url, path + parameterString.ToString().TrimEnd(new char[] { '&' }));
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Credentials = credential;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
{
throw new HttpException((int)response.StatusCode, response.StatusDescription);
}
XDocument xmlDoc = XDocument.Load(response.GetResponseStream());
return xmlDoc;
}
}
catch (Exception ex)
{
throw;
}
}
/*
I use this class for internal web services. For external web services, you'll want
to put some logic in here to determine whether or not you should accept a certificate
or not if the domain name in the cert doesn't match the url you are accessing.
*/
private static bool AcceptCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Linq;
using System.Configuration;
using Test.Entities;
namespace Test.Infrastructure
{
public class PersonRepository
{
private HttpService _httpService;
public PersonRepository()
{
_httpService = new HttpService();
}
public IQueryable<Person> GetPeople()
{
try
{
Uri host = new Uri("http://www.yourdomain.com");
string path = "your/rest/path";
Dictionary<string, string> parameters = new Dictionary<string, string>();
//Best not to store this in your class
NetworkCredential credential = new NetworkCredential("username", "password");
XDocument xml = _httpService.Get(host, path, parameters, credential);
return ConvertPersonXmlToList(xml).AsQueryable();
}
catch
{
throw;
}
}
private List<Person> ConvertPersonXmlToList(XDocument xml)
{
try
{
List<Person> perople = new List<Person>();
var query = xml.Descendants("Person")
.Select(node => node.ToString(SaveOptions.DisableFormatting));
foreach (var personXml in query)
{
people.Add(ObjectSerializer.DeserializeObject<Person>(personXml));
}
return people;
}
catch
{
throw;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Test.Entities;
using Test.Infrastructure;
using System.Net;
using System.Text;
namespace Test.Controllers
{
public class PeopleController
{
private PersonRepository _personRepository;
public PeopleController()
{
_personRepository = new PersonRepository();
}
public List<Person> List()
{
return _personRepository.GetPeople().ToList<Person>();
}
}
}