How to access data annotation through wcf service layer of a model - asp.net-mvc

I have created a Model and i want to access model data annotation like DisplayName.
I have access model through WCF service layer. But WCF service remove all the Data annotation of the model.
[DisplayName("Student Name")]
public virtual string StudentName
{
get
{
return this.m_StudentName;
}
set
{
this.m_StudentName= value;
}
}
I want to access Display Name in the View but always I get null value in the DisplayName method in through the Property

A WCF service does not remove anything. However, building a service reference is making a copy of all the classes you have. And that copy is the smallest set neccessary to run the service.
If you need your full classes, put all those classes and interfaces you want shared into a common library that both your service and your client reference. This is commonly called a contract assembly. You can then either call the service directly through code or if you want to keep the wizard, you can use the checkbox that says "use classes in this project" when generating new types.

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

What to return from service to ASP MVC web app?

Right now I have an ASP MVC web application along a Models project, a Service project, an Utilities project, and a few Datastores projects that function as repository for one or more domain models. I'm pretty happy with the separation of each layer but I'm stuck on what to return from service layer to the web app.
For example, when a user try to register, a RegisterViewModel is received by the controller. Individual pieces (email, password, etc.) are send to service layer which construct the Member domain object with guid, status, createdate, etc., send it to repository for storage and finally return the Member object for the web app to redirect to /Member/{guid}.
But how should the service layer inform the web app if an email already exists? In a more complex situation I may have to check the existence/validity of multiple domain objects and business rules so would have to return multiple errors in one go. In addition, I don't want exception to bubble to the web layer so service layer traps all exceptions but need to notify the web layer some how.
Even if I find a way to return all that, the web layer would be burdened to process all that and provide user various feedback. The controller code would be bulky and error prune. Is there a best practice on service result to the presentation? Should I eliminate separate service layer and have the code inside controller? Any thoughts are welcomed.
I wrote the operation model library for this purpose, which allows you to write code like this:
public OperationResult Register(RegisterInput input) {
var errors = new ErrorBuilder();
if (errors.NotValid(input) // Invoke DataAnnotations validation
|| errors.Not(this.repo.FindUserByEmail(input.Email) == null, "Email '{0}' already exists.", () => input.Email))
return errors;
// Do stuff
return HttpStatusCode.OK;
}
...and in the controller the error messages are copied to ModelState:
[HttpPost]
public ActionResult Register(RegisterInput input) {
var result = this.service.Register(input);
if (result.IsError)
return View().WithErrors(result);
// Do stuff
}
Check out the source code of the MvcAccount project which is written using this pattern.
First of all you need to decide if you are writing service layer for distribution purposes or not.
If you are not planning to distribute the service layer to a different process/machine,
Create a Message class
Create an array of message classes and store it in
HttpContext.Items
Now add any new message in any layer in to that array
consume it in the views/controller
HttpContext.Items is available for the life time of the request and you can use it all the way up to views.
If you use a DI framework you can achieve the same by using a request per life time object.
If you want to distribute the object nothing wrong in throwing the exceptions from your service layer.

Validation approach on MVC3 CRUD application with EF4-based WCF as backend

I develop a simple MVC3 CRUD application - simple controllers / views, which uses WCF service for CRUD data access.
The WCF uses EF4.1 with DbContext, and simple CRUD-style methods: ListEntities, GetEntity(ID), AddEntity (entity), DeleteEntity(ID)
If I develop the MVC application directly with EF, code first, I can annotate properties in the entity classes with validation attributes, and the MVC application will automatically recognize validation errors and report them in the UI when I try to save and a validation error occurs (e.g. a required field is not set).
But in my application I don't use this approach and I face two problems:
My entities in the WCF are generated from the EDMX, which in turn was also generated from the database. So I cannot actually add to them any data validation annotation attributes, because they'll vanish as soon as the entities will be regenerated from the EDMX. Is there any solution to this?
Since my client (MVC app) does not share the data contract classes with WCF (for clear separation), but instead it is generated form service reference, even if I find a way to add data annotation attributes to server-side data contract classes, will they be recognized and recreated when the data contract proxy class is created on client side?
So how could I made the MVC application to use client side validation and error message reporting for validation failures when binding to entities exposed by WCF service as data contracts?
One idea I have is, on client side, to create derived classes for all entities exposed as data contracts, and apply annotation attributes to them to desired properties. But this doesn't looks like a good solution to me, because with this I create a logic "coupling" between UI client and the WCF service / data layer (forcing UI to know about data more than it should do - by putting BL logic in client).
Can anyone give me some suggestions on how to handle those this situation?
Thanks
1: Yes you can add validation using the System.ComponentModel.DataAnnotations.MetaDataType.
I answered this question at MVC Partial Model Updates
2a: What you can do is create a seperate Class Library Assembly that contains all the interfaces (with or without additional MetaDataTypes) and use that on both the WCF service and the MVC application. After you add the reference to your MVC application, when adding the WCF Service reference, you can match the WCF Service DataContacts directly to the interfaces in the Assembly. One Caveat is that both the WCF service and MVC application are dependant on the Assembly (some might consider this tightly coupled) but this should be ok because you are only tightly coupling at the interface level, and whether or not you choose to allow VS to recreate it's own interfaces/classes or reuse what you already created in the Assembly it boils down to the same thing in my opinion.
2b: If you decide not to use a Class Library, I'm pretty sure that the service reference classes are partial, and you can simply create another .cs file with partial classes and add the interfaces as I described in part 1 to the partial classes.
Update
I am currently using Entity Framework to access my database. Entity Framework, like WCF References, classes are Auto-Generated classes will look something similar to:
[EdmEntityTypeAttribute(NamespaceName="MyNameSpace", Name="Info ")]
[Serializable()]
[DataContractAttribute(IsReference=true)]
public partial class Info : EntityObject
{
public static Info CreateInfo (global::System.Int32 id)
{
Info info= new Info ();
info.Id = id;
return info;
}
public string Name { get; set; }
public string FavoriteColor { get; set; }
// etc etc
}
In a separate file with the same namespace as the previous partial class, I have created:
[SomeAttribute1]
[AnotherAttribute2]
public partial class Info: IInfo
{
}
So now my auto-generated class is not only based on an Interface I created IInfo so the actual methods are not exposed (because my datatier in MVC returns interfaces), but it also has Attributes (for Data Annotations or whatever).
What I would suggest is instead of putting your data annotations directly on your WCF Service reference class is to use the MetedataType DataAnnotations. This allows you to separate the actual data object with the data annotations validations. Especially helpful if you want to use the same data class with different validations based on whatever (maybe administrators don't have to have a valid favorite color).
For example:
public interface NormalUser
{
[Required]
string Name { get; set; }
[Required]
string FavoriteColor { get; set; }
}
public interface AdminUser
{
[Required]
string Name { get; set; }
string FavoriteColor { get; set; }
}
[MetadataType(typeof(INormalUser))
public class NormalUserInfo : Info { }
[MetadataType(typeof(IAdminUser))
public class AdminUserInfo : Info { }
In this example we have two different classes NormaUserInfo and AdminUserInfo which both have different validations. Each of them have inherited from Info so they are valid models that can be passed into the WCF Service.
Out of my mind, as I can't test it right now...
Let's say your autogenerated code is like this:
public partial class Employee
{
//some code here
}
You can add a new Employee class, also partial, and this one won't be autogenerated
[you can annotate here]
public partial class Employee
{
//somecode here
}
try it
As for the validation, you could use: http://fluentvalidation.codeplex.com/

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

Exposing class structure through WCF?

I have a simple class that contains the required properties for a request to the service.
I want a consumer to instantiate this class on their end, fill it up, then pass it back to the service. Maybe the terminology I'm using isn't exactly right, but I'm sure I've read some project notes in the past where this was possible on other systems.
[DataContract]
public class SearchRequestObject
{
[DataMember]
public string WebsiteGuid { get; set; }
}
I have both DataContract and DataMember set in my service project. Once I publish it and consume it on another project, I don't see SearchRequestObject anywhere. I'm guessing this is because it has to be defined in the service's interface? If so, how?
Thanks.
Typically, SearchRequestObject would be one of the objects used in one of your service methods, for instance:
[ServiceContract(ConfigurationName = "IWCFService")]
public interface ICascadeManagementService
{
[OperationContract(Action = "http://tempuri.org/IWCFService/DoSearch")]
SearchResponseObject DoSearch(SearchRequestObject searchRequest);
}
When your client classes are then automatically generated, they will include a SearchRequestObject in the reference.cs file which contains the definitions.
If it's already being included in a method, it may not be being generated because your client project has a direct reference to the project in which SearchRequestObject is defined, and when you create the service reference you're reusing types from referenced assemblies. You can check if you have the reference in the references list of the client project, and if you're reusing types from referenced assemblies in the Advanced section of the Add Service Reference dialog.

Resources