MVC with WCF service design - asp.net-mvc

Being new to MVC, and WCF (somewhat), I'd like to ask a design question. I have an MVC application, with a simple screen. I need to call a WCF service, which returns a reply object type. To separate the WCF calls from my MVC app, I have created a ServiceProxy dll, which exposes a method called RegisterWithService, passing it an IP address.
So, MVC app, calls
ServiceProxy.RegisterWithService(xxx.xxx.xxx.xxx);
The method then creates a RegistrationRequest object, and sends that to the WCF service. The reply (a RegisterResponce object) replies with an object.
My question is, is it OK to pass that object back to the MVC controller to deal with, or should I create some form of DTO... so that the ServiceProxy creates a new object type (maybe, RegistrationDTO, which has the same fields as the WCF reply object, and passes that back to the MVC app? That, I guess, makes the MVC non-reliant on the WCF objects... so a change in the service contract would only cause a change in the proxy class I created - leaving the MVC app segregated.
Does that seem like a good design?

I think that 2 levels of objects are enough:
Domain models (coming from your WCF service)
View models (specific to the MVC application)
So you could use the service proxy interface that was generated for you when you imported the WCF service definition as repository layer. This interface will return your data contracts which will represent the domain models. The Controller will be responsible for calling various methods on this interface and mapping the domain models to view models that will be passed to the view.
For example:
public class HomeController: Controller
{
private readonly IServiceProxy service;
public HomeController(IServiceProxy service)
{
this.service = service;
}
public ActionResult Index(int id)
{
SomeDataContract domainModel = this.service.Get(id);
MyViewModel model = Mapper.Map<SomeDataContract, MyViewModel>(domainModel);
return View(model);
}
}
Of course if your application gets more complex you could introduce an additional abstraction layer and DTOs.

Related

ServiceStack new service side by side ASP.NET MVC website

In the examples for ServiceStack I don't see a single application that is ASP.NET MVC website first and then made ServiceStack service second.
Let's take a very simple ASP.NET MVC web application that renders products through Views. It uses controllers, views, models and viewmodels.
Let's say we have a model of Product which gets persisted into a document DB. Let's assume we have a viewmodel of ProductViewModel which gets mapped from Product and display within MVC Razor View/PartialView.
so this is a web side of things..now let's assume we want to add a service returning products to various clients like the Windows 8 applications.
Should the request/response classes be completely disconnected from what we already have? Our ProductViewModel might already contain everything we want to return from the service.
Since we already have Product (model class) we can't have another Product class in the API namespace..well we could but that makes things unclear and I'd like to avoid that.
So, should we introduce standalone ProductRequest class and ProductRequestResponse (inherits ProductViewModel) class in the API namespace?
Like so ProductRequestResponse : ProductViewModel?
What i'm saying is, we already have the Model and ViewModel classes and to construct Request and Response classes for the SS service we would have to create another two files, mostly by copying everything from the classes we already have. This doesn't look DRY to me, it might follow the separation of concerns guidelines but DRY is important too, actually more than separating everything (separating everything leads to duplication of code).
What I would like to see is a case where a web application has already been made, it currently features Models and ViewModels and returns the appropriate Views for display on the Web but can be extended into a fully functional service to support programmatic clients? Like AJAX clients etc...with what we already have.
Another thing:
If you take a look at this example https://github.com/ServiceStack/ServiceStack.Examples/blob/master/src/ServiceStack.MovieRest/MovieService.cs
you will see there is Movie Request class and Movies Request class (one for single movie request, the other one for a list of movies). As such, there are also two services, MovieService and MoviesService, one dealing with requests for a single movie, the other one for a genre of movies.
Now, while I like SS approach to services and I think it is the right one, I don't like this sort of separation merely because of the type of request. What if I wanted movies by director? Would I be inventing yet another request class having a Director property and yet another service (MoviesByDirector) for it?
I think the samples should be oriented towards one service. Everything that has to deal with movies need to be under one roof. How does one achieve that with ServiceStack?
public class ProductsService : Service
{
private readonly IDocumentSession _session;
private readonly ProductsHelperService _productsHelperService;
private readonly ProductCategorizationHelperService _productCategorization;
public class ProductRequest : IReturn<ProductRequestResponse>
{
public int Id { get; set; }
}
// Does this make sense? 
// Please note, we use ProductViewModel in our Views and it holds everything we'd want in service response also
public class ProductRequestResponse : ProductViewModel
{
}
public ProductRequestResponse GetProducts(ProductRequest request)
{
ProductRequestResponse response = null;
if (request.Id >= 0)
{
var product = _session.Load<Product>(request.Id);
response.InjectFrom(product);
}
return response;
}
}
The Service Layer is your most important Contract
The most important interface that you can ever create in your entire system is your external facing service contract, this is what consumers of your service or application will bind to, i.e. the existing call-sites that often won't get updated along with your code-base - every other model is secondary.
DTOs are Best practices for remote services
In following of Martin Fowler's recommendation for using DTOs (Data Transfer Objects) for remote services (MSDN), ServiceStack encourages the use of clean, untainted POCOs to define a well-defined contract with that should kept in a largely implementation and dependency-free .dll. The benefits of this allows you to be able to re-use typed DTOs used to define your services with, as-is, in your C#/.NET clients - providing an end-to-end typed API without the use of any code-gen or other artificial machinery.
DRY vs Intent
Keeping things DRY should not be confused with clearly stating of intent, which you should avoid trying to DRY or hide behind inheritance, magic properties or any other mechanism. Having clean, well-defined DTOs provides a single source of reference that anyone can look at to see what each service accepts and returns, it allows your client and server developers to start their work straight away and bind to the external service models without the implementation having been written.
Keeping the DTOs separated also gives you the freedom to re-factor the implementation from within without breaking external clients, i.e. your service starts to cache responses or leverages a NoSQL solution to populate your responses with.
It's also provides the authoritative source (that's not leaked or coupled inside your app logic) that's used to create the auto-generated metadata pages, example responses, Swagger support, XSDs, WSDLs, etc.
Using ServiceStack's Built-in auto-mapping
Whilst we encourage keeping separate DTO models, you don't need to maintain your own manual mapping as you can use a mapper like AutoMapper or using ServiceStack's built-in Auto Mapping support, e.g:
Create a new DTO instance, populated with matching properties on viewModel:
var dto = viewModel.ConvertTo<MyDto>();
Initialize DTO and populate it with matching properties on a view model:
var dto = new MyDto { A = 1, B = 2 }.PopulateWith(viewModel);
Initialize DTO and populate it with non-default matching properties on a view model:
var dto = new MyDto { A = 1, B = 2 }.PopulateWithNonDefaultValues(viewModel);
Initialize DTO and populate it with matching properties that are annotated with the Attr Attribute on a view model:
var dto = new MyDto { A=1 }.PopulateFromPropertiesWithAttribute<Attr>(viewModel);
When mapping logic becomes more complicated we like to use extension methods to keep code DRY and maintain the mapping in one place that's easily consumable from within your application, e.g:
public static class MappingExtensions
{
public static MyDto ToDto(this MyViewModel viewModel)
{
var dto = viewModel.ConvertTo<MyDto>();
dto.Items = viewModel.Items.ConvertAll(x => x.ToDto());
dto.CalculatedProperty = Calculate(viewModel.Seed);
return dto;
}
}
Which is now easily consumable with just:
var dto = viewModel.ToDto();
If you are not tied specifically to ServiceStack and just want "fully functional service to support programmatic clients ... with what we already have", you could try the following: Have your controllers return either a ViewResult or a JsonResult based on the request's accept header - Request.AcceptTypes.Contains("text/html") or Request.AcceptTypes.Contains("application/json").
Both ViewResult and JsonResult are ActionResult, so the signature of actions remains the same, and both View() and Json() accept a ViewModel. Furthermore, if you have a ControllerBase you can make a base method (for example protected ActionResult RespondWith(Object viewModel)) which calls either View() or Json() so the change to existing code is minimal.
Of course, if your ViewModels are not pure (i.e. have some html-specific stuff or you rely on some ViewBag magic) then it's a little more work. And you won't get SOAP or other binding types provided by ServiceStack, but if your goal is to support a JSON data interface with minimal code changes to the existing MVC app then this could be a solution.
Lp

How are you populating/validating your ViewModels?

I'm curious of all of the various ways people are building their ViewModels and why they choose that method.
I can think of several ways here:
-1. Injected repository - the controller loads the model and maps to the ViewModel. Here the ViewModel constructor could take various collections to interally set for ex. in a select list such as:
public CustomerController(ISomeRepository repository)
{
_repository = repository;
}
public ActionResult Create()
{
CustomerCreateViewModel model = new CustomerCreateViewModel(_repository.GetShipTypes,
_repository.GetStates);
..
..
}
-2. ViewModelBuilder - Either injected or instantiated in the controller with an instance of the injected repository. Called via something like
>var orderViewModel = orderViewModelBuilder.WithStates().Build(orderId);
or,
var orderViewModel = orderViewModelBuilder.WithStates().Build(orderId);
-3. Directly in controller (no code required - its messy)
-4. Some other service (injected or not) that returns domain model which the controller then maps or a ViewModel (anyone doing this to return a view model that isn't specifically named/noted as a ViewModel builder class?)
public JobCreateViewModel BuildJobCreateViewModel(int parentId)
{
JobCreateViewModel model = new JobCreateViewModel();
model.JobStatus = _unitOfWork.JobRepository.GetJobStatuses();
model.States=_unitOfWork.StateRepository.GetAll();
return model;
}
Now on the return trip - regarding validating your view models - are you inheriting from a base ViewModel class for standard validations, or copying your validations (ex. data annotation attributes) between all of your ViewModels, or simply relying on server side validation so it can all be validated againt your domain object?
Any others? Anything better? Why?
EDIT
Based on a link below, I did find a nice article from Jimmy Bogard on the architecture of ViewModels. While it doesn't address the question above directly, it's a great reference for anyone coming here for ViewModel information.
http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/
I inject a service into the controller, not a repository, and then use AutoMapper to convert it into a view model. The benefit of the service layer in this case is that it could aggregate multiple simple operations from one or more repositories into a single operation exposing a domain model. Example:
private readonly ICustomerService _service;
public CustomerController(ICustomerService service)
{
_service = service;
}
[AutoMap(typeof(Customer), typeof(CustomerViewModel))]
public ActionResult Create(int id)
{
Customer customer = _service.GetCustomer(id);
return View(customer);
}
in this example AutoMap is a custom action filter that I can write which executes after the controller action, inspects the returned object and uses defined AutoMapper mappings to map it to the specified destination type. So the view gets the corresponding CustomerViewModel as model type. Would have been equivalent to:
public ActionResult Create(int id)
{
Customer customer = _service.GetCustomer(id);
CustomerViewModel vm = Mapper.Map<Customer, CustomerViewModel>(customer);
return View(vm);
}
it's just that it is too much plumbing and repetitive code that could be centralized.
I would also recommend you watching the putting your controllers on a diet video from Jimmy Bogard.
I just finished a project where we did a variation on #4. We had a service class injected into the controller. The service class held dependencies on the repository and a model builder class (we called it model factory).
The controller called into the service class, which handled business validation logic, and then fetched view models from the appropriate factory. The models themselves relied on data annotations for input validation.
It worked really well for our team. There was enough separation of concerns to allow the devs to do their work without affecting one another, but it was manageable enough to understand what was going on.
It's the first time we tried it and we'll be sticking with it. I'm interested to see how others respond.
Our method is to inject the repository in to the controller and map it to the ViewModel using Automapper http://automapper.org/. Our ViewModels contain data annotation attributes to allow the validation to occur on the client.
We call methods on the repository which return Domain objects (Entity Framework). The domain objects are mapped to the ViewModel. We tend to use the same ViewModel for edits and adds so the data annotations are needed once. In its simplest form it looks like the following code:
public ActionResult List(int custId, int projId)
{
var users = _userRepository.GetByCustomerId(custId);
var userList = Mapper.Map<IEnumerable<CMUser>, IEnumerable<UserListViewModel>>(users);
return View(userList);
}
I use a service layer that hides the domain model from the controller returning ViewModels from the service methods. This allows me to make changes to the domain model without impacting the client.

WCF with ASP.NET MVC - Reference Projects

on a ASP.NET MVC project, the data access layer is going to be implemented in WCF. Reason is that these WCF services are going to be consumed by couple of other client applications in the future.
Can I know whether there are any good reference projects that I can have a look at.
Important things that I need to have a look at are:
How the projects are structured
Any best practices that need to be followed
How Domain objects/POCOs, DTOs, ViewModels need to be organized, and communicate between each other
Unit Testing approaches
All your suggestions/advices on these areas are highly appreciated
Thank you very much.
You would do exactly the same as if you were doing any other ASP.NET MVC application. You would simply provide an implementation of your repository which would call the WCF service. So basically your repository interface could be the operation contract you got when you imported your service:
public interface IProductsService
{
IEnumerable<Product> GetProducts();
}
Product and IProductsService are domain objects coming from your WCF service. In the implementation of this interface you would delegate the call to the service itself. As far as the rest of the application is concerned, your controllers doesn't really care as they are weakly coupled:
public class ProductsController: Controller
{
private readonly IProductsService _productsService;
public ProductsController(IProductsService productsService)
{
_productsService = productsService;
}
public ActionResult Index()
{
var products = _productsService.GetProducts();
var productsVm = Mapper.Map<IEnumerable<Product>, IEnumerable<ProductViewModel>>(products);
return View(productsVm);
}
}
Pretty standard stuff and it is how your controllers should look like no matter where the data comes from. As you can see if you always design your applications with abstractions you could very easily switch implementation of this IProductsService that will be injected into your controllers and from the ASP.NET MVC application standpoint it wouldn't even make any difference. The view models should be part of the web UI as they are strongly tied to the views.
The service contracts and domain models go into a service layer.

Problem with WCF Data service exposing custom partial methods of EF4 model

I am exploring the idea of implementing a web service api using WCF Data Services and EF4. Realizing that some operations require complex business logic, I decided to create a partial class the same name as the main EF data context partial class and implement additional methods there to handle the more complex business logic. When the EF context object is used directly, the additional method shows up (via intellisense) and works properly. When the EF classes are exposed through a WCF Data Service and a Service Reference is created and consumed in another project, the new method does not show up in intellisense or in the generated Service.cs file (of course, I updated the reference and even deleted it and re-added it). The native data methods (i.e. context.AddObject() and context.AddToPeople()) work properly, but the new method isn't even available.
My EF classes look something like this:
namespace PeopleModel
{
//EF generated class
public partial class PeopleEntities : ObjectContext
{
//Constructors here
//Partial Methods here
//etc....
}
//Entity classes here
//My added partial class
public partial class PeopleEntities
{
public void AddPerson(Person person)
{
base.AddObject("People", person);
}
}
}
There's nothing special about the .svc file. The Reference.cs file containing the auto generated proxy classes do not have the new "AddPerson()" method.
My questions are:
1. Any idea why the web service doesn't see the added partial class, but when directly using the EF objects the method is there and works properly?
2. Is using a partial class with additional methods a good solution to the problem of handling complex business rules with an EF generated model?
I like the idea of letting the oData framework provide a querying mechanism on the exposed data objects and the fact that you can have a restful web service with some of the benefits of SOAP.
Service operations are only recognized if they are present on the class which derives from DataService. The WCF Data Service will not look into the context class for these. Also note that methods are not exposed by default, you need to attribute them with either WebGet or WebInvoke and allow access to them in your InitializeService implementation.
http://msdn.microsoft.com/en-us/library/cc668788.aspx

ASP.NET MVC Dependency Injection Unity with WCF services - working sample solution

I'm looking for a working sample of an ASP.NET MVC web application that uses Unity and calls an WCF service. I've looked at a lot of explanations on how to add dependency injection to WCF services but frankly I'm a little over my head here. It doesn't help that I'm new to WCF services as well.
I'm currently using Unity with Contructor injection for our ASP.NET MVC applications but so far we aren't using any WCF Web Services. The plan is to start using web services and I'm very confused on how to incorporate Unity with them.
I would love a nice working sample that I could walk through to better understand how to go about it.
I will try to provide you with some guidance.
Let's suppose that you have an existing products WCF service that is defined like this (we don't care about the implementation, that's not important for the moment, you could implement it as you wish, varying from hardcoded values, passing through a SQL database and an ORM, to consuming another service on the cloud):
[DataContract]
public class Product
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
}
[ServiceContract]
public interface IProductsService
{
[OperationContract]
Product Get(int id);
}
Now in your ASP.NET MVC application the first step is to add a service reference to it by pointing to the WSDL. This will generate proxy client classes.
Next you could add the Unity.Mvc3 NuGet package to your MVC application
Then in your Application_Start you could configure the container (obviously this configuration could be externalized into a separate method to avoid cluttering your Global.asax with it):
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
var container = new UnityContainer();
container
.RegisterType<IProductsService, ProductsServiceClient>()
.Configure<InjectedMembers>()
.ConfigureInjectionFor<ProductsServiceClient>(new InjectionConstructor("*"));
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
IProductsService and ProducsServiceClient used in this configuration are the proxy classes generated when you imported the web service definition.
From now on things become trivial:
public class HomeController : Controller
{
private readonly IProductsService _productsService;
public HomeController(IProductsService productsService)
{
_productsService = productsService;
}
public ActionResult Index()
{
var product = _productsService.Get(1);
return View(product);
}
}
and some corresponding Index view:
#model Product
<div>
#Html.DisplayFor(x => x.Name)
</div>
As you can see from this example thanks to the IProductsService abstraction, HomeController is totally decoupled from any concrete implementations of the service. In Today in your Global.asax you decided to use WCF (ProductsServiceClient), but tomorrow you could decide to use some completely different implementation. With a single changes in your DI container configuration you could switch the implementation. Thanks to this weak coupling, your controllers are fully unit testable in isolation.
What is important to realize here is that your business is the Product class and the IProductsService interface. This is what reflects your domain. This is the M in MVC. Implementations could change, but this should stay the same, otherwise you have wrongly identified your business requirements which could be catastrophic in long term.
Remark: one thing that I haven't covered in this example, and which is very important, is the usage of view models. In a properly architected ASP.NET MVC application you should never pass domain models to your views (in this example the Product class). You should use view models. View models are classes that are specifically designed for the requirements of a given view. So in a real world ASP.NET MVC application you would have a ProductViewModel class which to which the Product domain model will be mapped in the controller action and it is this ProductViewModel that will be passed to the view. Those view models should be defined in the MVC project as, contrary to your domain models, they are not reusable and reflect only the specific requirements of a single view. To ease the mapping between your domain models and view models you may take a look at AutoMapper.
It sounds like you're already injecting your MVC Controllers using Unity and all you want to do is start injecting the WCF services you host as well. To inject WCF services, you need to use an IInstanceProvider.
Complete working solution is here:
http://orand.blogspot.com/2006/10/wcf-service-dependency-injection.html
You need 4 very very simple classes:
MyServiceHostFactory
MyServiceHost
DependencyInjectionServiceBehavior
DependencyInjectionInstanceProvider
define those, specify your new ServiceHostFactory:
<%# ServiceHost
Service="NamespaceC.ServiceLayer, AssemblyC"
Factory="NamespaceD.MyServiceHostFactory, AssemblyD"
%>
and you're done.
I know it's a bit late in the game, but I've written a Nuget package to simplify the process of using WCF in your MVC/WebApi app, and it leverages Unity.
Check out Unity.Mvc.Wcf on Codeplex or GitHub for details.

Resources