对于MVC3应用程序,我想创建一个可以作为服务访问的可重用DAL,因为这将在未来用于其他项目。
我created all the entities将TT模板和EFCodeFirst放在一个单独的项目中,然后在RESTful WCF服务中使用它。
这个服务的结构与我编写的其他WCF服务有点不同,我在服务接口中指定了RESTful签名和可选的JSON响应作为方法装饰器,即:
[WebGet(UriTemplate = "GetCollection")]
public List<SampleItem> GetCollection()
{
// TODO: Replace the current implementation to return a collection of SampleItem instances
return new List<SampleItem>() { new SampleItem() { Id = 1, StringValue = "Hello" } };
}
[WebInvoke(UriTemplate = "", Method = "POST")]
public SampleItem Create(SampleItem instance)
{
// TODO: Add the new instance of SampleItem to the collection
throw new NotImplementedException();
}
这个RESTful WCF服务(从RESTful WCF选项创建)不同的地方是没有接口,我可以用我需要的东西来装饰服务方法 - 没关系。该服务将公开GetUserByID(int id)等方法。
问题是我想在MVC3应用程序中使用它,并且不清楚如何将模型连接到我的服务,并希望有一些方向来实现这一点。
感谢。
答案 0 :(得分:0)
考虑这一点的方法是,您的MVC应用程序现在只知道您的服务。它不知道背后有DAL。基本上,将服务视为“持久性”层。所以,现在你的MVC模型必须使用该服务填充自己。因此,就像任何其他应用程序将填充服务一样,这就是您的模型将如何填充自己。然后您的控制器将使用您的模型返回您的视图。
这不是你可能正在寻找的细节,但是有很多关于如何在.NET中使用RESTful服务的资源。检查那些,并让那些填充你的模型。然后让你的模型进入你的视野。
答案 1 :(得分:0)
假设您要公开名为Person的实体。 WCF REST服务可能如下所示:
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public partial class PeopleWebService
{
[WebGet(UriTemplate = "")]
public List<Person> GetCollection()
{
try
{
IPeopleRepository repository = ServiceLocator.GetInstance<IPeopleRepository>();
var people = repository.GetPeople();
// use automapper to map entities to Person resource
var result = Mapper.Map<List<Person>>(people);
return result;
}
catch (Exception exception)
{
// do logging etc
throw new WebFaultException(HttpStatusCode.InternalError);
}
}
/* other methods */
}
这些服务也可以由T4生成。
请注意,WCF服务本身不需要接口。我通常不直接在WCF服务中公开任何数据库实体,因为我的服务演变与我的数据库实体不同。一旦API发布,它应该几乎保持不变。这可以防止我更改我的数据库架构以适应新的要求。
相反,我将我的实体映射到资源。所以Person
可能如下所示:
[DataContract]
public class Person
{
[DataMember]
public string GivenName { get; set; }
/ * more properties */
}
使用T4生成这些也可能是一件好事。路由定义如下:
public void Register(RouteCollection routes)
{
routes.AddService<WorkspaceWebService>("api/v1/people");
}
要从ASP.NET MVC项目中使用它,您可以将上面定义的资源(也称为Person)作为程序集共享,或者您可以使用T4生成几乎相同的单独资源集,但是ASP.NET MVC所需的一些其他属性,如用于验证的属性。我会生成它,因为我的ASP.NET MVC视图模型通常独立地发展到我的REST资源。
假设您的REST服务在https://api.example.com/运行,而您的MVC网站在https://www.example.com/运行。您的PeopleController可能如下所示。
public class PeopleController : ControllerBase
{
[HttpGet]
public ActionResult Index()
{
return View(Get<List<Person>>(new Uri("https://api.example.com/api/v1/people")));
}
protected T Get<T>(Uri uri)
{
var request = (HttpWebRequest) WebRequest.Create(uri);
request.Method = "GET";
request.ContentType = "text/xml";
using (var response = (HttpWebResponse) request.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
Debug.Assert(responseStream != null, "responseStream != null");
var serializer = new DataContractSerializer(typeof (T));
return (T) serializer.ReadObject(responseStream);
}
}
}
}
根据您的问题,我假设您要使用JSON。为此,您只需在请求上设置适当的ContentType并使用DataContractJsonSerializer而不是DataContractSeralizer。请注意,日期和DataContractJsonSerializer存在一些问题。如果contenttype是“text / xml”,WCF rest服务将自动返回XML,如果是“application / json”,则自动返回JSON。
请注意,MVC应用程序不了解数据库,数据库实体或其数据库上下文。事实上,MVC应用程序中没有数据库逻辑。您必须密切关注安全性,因为WCF休息服务中缺少用户上下文。但是,这是一个完全不同的讨论。