Предположим, вы хотите раскрыть сущность с именем Person. Служба REST WCF может выглядеть следующим образом:
[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. Служба отдыха WCF будет автоматически возвращать XML, если тип содержимого - «text / xml», и JSON, если это «application / json».
Обратите внимание, что приложение MVC не знает о базе данных, объектах базы данных или ее контексте базы данных. На самом деле в приложении MVC нет логики базы данных. Вам придется обратить пристальное внимание на безопасность, потому что пользовательский контекст отсутствует в остальных сервисах WCF. Но это совсем другое обсуждение.