I want to expose legacy .net code via WCF Data Services. But without using Entity Framework anywhere. Basically I currently populate all my models from db once every X hours and dump these models in cache. The current web services pull all the info from this cache. I now have to convert all of this to WCF Data Services, primarily to support OData protocol.
What is the simplest and quickest way out (again, no entity framework)
Below is an example of how my model currently looks like:
public class Country
{
public string CountryCode {get; set;}
public string CountryName {get; set;}
public List<State> ListOfStates {get; set;}
}
public class State
{
public string StateCode {get; set;}
public string StateName {get; set;}
}
Thanks in advance.
You need to use reflection provider instead of Entity framework provider - custom context class exposed in WCF Data Service. Just be aware that reflection provider by default expose only read only data. If you need to update data through your OData service you will also have to implement IUpdateble interface on your context class.
It's not black magic - but a bit of work.
See this WCF Data Services Advanced Topics article which shows how you could use e.g. Subsonic for your ORM.
Basically, the steps involved are:
you need to expose IQueryable<T> collections for all your classes - you could do this by having some kind of a DataModel or DataContext class that contains all those collections
If you want to be able to insert and update data, you also need:
to implement the IUpdatable interface on your "data context" to enable change tracking and handling of CUD operations
I don't want to advertise myself actually, but your problem is the same situation we had here at work. We've taken over the original toolkit developed by Jonathan Carter for mapping WCF DataServices to whatever you want them to be.
Try taking a look at http://wcfdstoolkit.codeplex.com/ and see if this solves your problem. The documentation is available through links to Jonathan's blog on how to setup & use the toolkit. But I recommend to download the september release branch, to ensure you have all bug fixes in it that I already solved.
Related
I am in the process converting a large classic ASP web application to ASP.Net MVC with domain driven design. While much of my domain fits well with DDD, I keep running into situations where a pure DDD approach is not appropriate. For example the read side of my application varies significantly from the write side. No problem, I created a separate read model, and implemented a simplified version of CQRS (no event sourcing, no separate db). Another issue was bulk database operations. No problem, that is being implemented as a service. Here's my current quandary. Our system allows users to make changes to the system that are effective on some future date. To accommodate this we have a database table that stores the pending changes until the effective date. On the effective date, an automated task runs and performs the actual database updates. The update task can include domain logic, so that part fits with DDD and is not a problem. To help visualize what is going on, here is the class that handles the pending update:
public class PendingChanges
{
public int EntityID {get; set;}
public string FromTable {get; set;}
public string DetailField {get; set;}
public string NewValue {get; set;}
public DateTime EffectiveDate {get; set;}
public DateTime EnteredDate {get; set;}
public int UserID {get; set;}
public string UserName {get; set;}
public string UserArea { get; set; }
// Business logic and validation here?
}
As you can see this is a generic class that can handle updates to various database tables. It basically stores the database column that is being updated, the new value that the column will be, the table that it belongs in, the effective date and some logging data.
So here are my questions: Should the logic that collects the pending update and stores it in the pending updates table be modeled as a domain object or should it be handled some other way, for example as a service?
To put it another way is PendingChanges itself a domain entity with its own domain logic? There are some business rules that apply to PendingChanges as distinct from the entities that the changes are taking place on. For example what constitutes a UserArea could be considered a business rule as would be legal values for FromTable, not to mention validation.
Or is PendingChanges a value object since it is reusable across different domain objects? If that is the case does it make more sense to use PendingUpdatesService?
Is part of the Domain the concept of doing db updates i.e are you building database management/reporting software? If PendingChanges has a meaning for your Domain then maybe is an entity, although this technicality matters less, getting the proper domain modelling is much more important. If PendingChanges is a class that your app is using to update (domain)things in the db, then it has nothing to do with DDD nor with your domain. It is a part of your infrastructure. Good OOP is still needed though, but no DDD buzzwords here.
Btw, if an object has an id, it usually is an Entity.
I'm new to MVC4 framework & been working on an Licensing application that must use different databases for different products (each database contains handful tables for one product - all generated by proprietary licensing tool). My application shall be able to support CRUD functions on various products, thus requiring more than one DbContext objects in relation to different model for each product.
As far as I know, each such DbContext object requires a connection string in the Web.config file. I'm struggling to list (Index.cshtml) existing licences for various products, using DropDownList control, as for each product I'd need to connect to a different database whenever the user choose a different product from the DropDownList control.
Any help will be highly appreciated. Thanks.
As I understand your question, the core issue is you are struggling to connect to a different db, whenever user selects a different product from a DropDownList. As you said, yes DbContext object requires a connection string in the Web.config file. You can specify multiple connection strings in a config.
Also you can definitely pass different connection strings to DBContext constructor. Typically your DAL/Data Access Layer or Repository layer would pull appropriate connection string from the Web.Config/App.config and pass it to the DBContext constructor. See a similar approach here and here.
UPDATE :
You cannot share the same DbContext with multiple databases. You need multiple DbContexts for each of your DB.
Additional
There are few of doing this, but if you use Repostory and Unit Of Work pattern, you can use an approach like this
Each DbContext you going to have, you can associate with set of entities within that database in context. Something like below
public class ProductContext : DbContext
{
public ProductContext ()
: base("connectionStringA")
{
}
public DbSet<Product> Accounts { get; set; }
}
public class LicenceContext : DbContext
{
public LicenceContext ()
: base("connectionStringB")
{
}
public DbSet<Licence> Licenses{ get; set; }
}
I am writing a Web API that clients can make requests to to return data in XML format. I am implementing this in .NET using Enterprise Foundation and MVC4.
I am struggling a bit with how to only return a subset of some fields from my Models in my Controllers.
For arguments sake, lets say I have a Product model that contains attributes "Id", "Name", "Price" and "Actual Cost" (I am using an example from http://www.asp.net/web-api/overview/creating-web-apis/using-web-api-with-entity-framework/using-web-api-with-entity-framework,-part-6)
I need to expose a Web API for clients to query a specific Product to get its name and price, but in this response I don't want to return the "Actual Cost" property (because this is our secret).
Now in the link I provide this is exactly the problem they are attempting to solve by the use of DTO's (they define a DTO called ProductDTO that contains only the subsets I want to return). I have implemented this solution and I am indeed now able to return only the fields I specify in the DTO.
The problem is that the naming used for the returned entity in XML is now ProductDTO rather than Product, i.e. the returned XML is
{"ProductDTO":[{"Id":1,"Name":"Tomato Soup","Price":1.39}, {"Id":3,"Name":"Yo yo","Price":6.99]}
rather than
{"Product":[{"Id":1,"Name":"Tomato Soup","Price":1.39}, {"Id":3,"Name":"Yo yo","Price":6.99]}
That means that all of our clients currently using our API and expects a "Product" to be returned will now get a "ProductDTO" returned, which means that they will have to make changes to their code and which is unacceptable. I need to provide them with a "Product" with only the relevant set of sub-fields as they are currently getting. How do I achieve this? I cannot simply "ignore" a data member as suggested in prevent property from being serialized in web api because I also have some API cases where I indeed DO need to return ALL the attributes and not only a subset.
Just some background: We have an existing API server interface that was written in Ruby on Rails and we are now moving this over to C# and .NET MVC4. We also have a bunch of client applications already interfacing to our existing, older, Ruby on Rails API Server and we don't want clients to make any changes to their code. We are simply moving our API server code over from Ruby on Rails to C#. In Ruby on Rails I was simply able to apply a filter to the XML Serializer when I need to only return a subset of attributes on certain calls.
If you want to continue down the DTO route that you have started, which IMHO is a good idea as it gives you control of what you export without polluting your internal classes with export specific stuff, you can add a DataContract attribute to your ProductDTO class.
[DataContract(Name="Product")]
public class ProductDTO
{
[DataMember]
public int Id {get;set;}
[DataMember]
public string Name {get;set;}
}
The default XML formatter used in Web API is the DataContractSerializer.
You can read more about this here
Suppose you have a class like
public class product
{
public string Name{get; set;}
..
}
and you don't want to appear it in the response you can just use [XMLIgnore] attribute
[XMLIgnore]
public string Name{get; set;}
hopes this helps.
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/
I need to make a web application and I want to use MVC. However, my Model can't be one of the standard Models -- the data is not stored in a database but instead in an external application accessible only via a API. Since this is the first MVC application I've implemented I'm relying on examples to understand how to go about it. I can't find any examples of a non-DB based Model. An example of a custom Model would be fine too. Can anyone point me to such a beast? Maybe MVC is just to new and none exist.
It seems like I might be able to get away with the DataSet Model, however I've not seen any examples of how to use this object. I expect an example of DataSet could help me also. (Maybe it is the same thing?)
Please note: I've seen countless examples of custom bindings. This is NOT what I want. I need an example of a custom Model which is not tied to a specific database/table.
UPDATE
I found a good example from MS located here:
http://msdn.microsoft.com/en-us/library/dd405231.aspx
While this is the "answer" to my question, I don't really like it because it ties me to MS's view of the world. #Aaronaught, #jeroenh, and #tvanfosson give much better answers from a meta perspective of moving my understanding (and yours?) forward with respect to using MVC.
I'm giving the check to #Aaronaught because he actually has example code (which I asked for.) Thanks all and feel free to add even better answers if you have one.
In most cases it shouldn't matter what the backing source is for the actual application data; the model should be exactly the same. In fact, one of the main reasons for using something like a repository is so that you can easily change the underlying storage.
For example, I have an MVC app that uses a lot of web services - rarely does it have access to a local database, except for simple things like authentication and user profiles. A typical model class might look like this:
[DataContract(Namespace = "http://services.acme.com")]
public class Customer
{
[DataMember(Name = "CustomerID")]
public Guid ID { get; set; }
[DataMember(Name = "CustomerName")]
public string Name { get; set; }
}
Then I will have a repository interface that looks like this:
public interface ICustomerRepository
{
Customer GetCustomerByID(Guid id);
IList<Customer> List();
}
The "API" is all encapsulated within the concrete repository:
public class AcmeWSCustomerRepository : ICustomerRepository, IDisposable
{
private Acme.Services.CrmServiceSoapClient client;
public AcmeWSCustomerRepository()
: this(new Acme.Services.CrmServiceSoapClient())
public AcmeWSCustomerRepository(Acme.Services.CrmServiceSoapClient client)
{
if (client == null)
throw new ArgumentNullException("client");
this.client = client;
}
public void Dispose()
{
client.SafeClose(); // Extension method to close WCF proxies
}
public Customer GetCustomerByID(Guid id)
{
return client.GetCustomerByID(id);
}
public IList<Customer> List()
{
return client.GetAllCustomers();
}
}
Then I'll also probably have a local testing repository with just a few customers that reads from something like an XML file:
public class LocalCustomerRepository : ICustomerRepository, IDisposable
{
private XDocument doc;
public LocalCustomerRepository(string fileName)
{
doc = XDocument.Load(fileName);
}
public void Dispose()
{
}
public Customer GetCustomerByID(Guid id)
{
return
(from c in doc.Descendants("Customer")
select new Customer(c.Element("ID").Value, c.Element("Name").Value))
.FirstOrDefault();
}
// etc.
}
The point I'm trying to make here is, well, this isn't tied to any particular database. One possible source in this case is a WCF service; another is a file on disk. Neither one necessarily has a compatible "model". In this case I've assumed that the WCF service exposes a model that I can map to directly with DataContract attributes, but the Linq-to-XML version is pure API; there is no model, it's all custom mapping.
A really good domain model should actually be completely independent of the true data source. I'm always a bit skeptical when people tell me that a Linq to SQL or Entity Framework model is good enough to use throughout the entire application/site. Very often these simply don't match the "human" model and simply creating a bunch of ViewModel classes isn't necessarily the answer.
In a sense, it's actually better if you're not handed an existing relational model. It forces you to really think about the best domain model for your application, and not necessarily the easiest one to map to some database. So if you don't already have a model from a database - build one! Just use POCO classes and decorate with attributes if necessary, then create repositories or services that map this domain model to/from the API.
I think what you are looking for is really a non-DB service layer. Models, typically, are relatively simple containers for data, though they may also contain business logic. It really sounds like what you have is a service to communicate with and need a layer to mediate between the service and your application, producing the appropriate model classes from the data returned by the service.
This tutorial may be helpful, but you'd need to replace the repository with your class that interacts with the service (instead of the DB).
There is no fixed prescription of what a "Model" in MVC should be, just that it should contain the data that needs to be shown on screen, and probably also manipulated.
In a well-designed MVC application, data access is abstracted away somehow anyway, typically using some form of the Repository pattern: you define an abstraction layer (say, an IRepository interface) that defines the contract needed to get and persist data. The actual implementation will usually call a database, but in your case should call your 'service API'.
Here is an example of an MVC application that calls out to a WCF service.