Given:
I'm trying to create a REST API using ASP.NET MVC.
I'm using NHibernate in my data access layer.
Problem:
I'm can't XmlSerialize ISet properties.
I get errors like the following:
Cannot serialize member
[namespace].[entity].[property] of
type
Iesi.Collections.Generic.ISet`1[[namespace].[entity],
[assembly], Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null]]
because it is an interface.
I'll freely admit: I'm very new to NHibernate.
So I don't know what my options are.
I believe that I need to use a set as opposed to a bag because my collections contain unique items.
When I converted the ISet properties to HashedTable properties (i.e. a concrete class), I got errors like the following:
You must implement a default accessor
on
Iesi.Collections.Generic.HashedSet`1[[namespace].[entity],
[assembly],
Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null]] because it
inherits from ICollection.
My questions:
What should I do to remedy this situation?
Should I implement default accessors in all of my entity classes?
If so, is there a recommended pattern for doing so?
As a sidenote, I tried Googling for help.
- I don't think this is a new problem.
NHibernate serialization has been treated a lot on stackoverflow. See:
C# Castle ActiveRecord: How to elegantly (XML) serialize ActiveRecord objects?
How do I serialize all properties of an NHibernate-mapped object?
NHibernate and WCF Serialization(Unidirectional)
JSON.NET and nHibernate Lazy Loading of Collections
Which .NET JSON serializers can deal with NHibernate proxy objects?
DTOs vs Serializing Persisted Entities
Returning NHibernate mapping classes from WCF services
Bottom line: use DTOs.
Try using the DataContractSerializer instead. It's more restrictive, but will serialize more.
Dan Rigsby explains the difference between XMLSerializer and DataContractSerializer
Here's an example from one of my posts on stackoverflow:
public XDocument GetProductXML(Product product)
{
var serializer = new DataContractSerializer(typeof(Product));
var document = new XDocument();
using (var writer = document.CreateWriter())
{
serializer.WriteObject(writer, product);
writer.Close();
}
return document;
}
You can never XML Serialize an interface - only a concrete class that implements the interface.
1) Load the Dozer bean mapper from mapping file
DozerBeanMapper dtoMapper = new DozerBeanMapper(Arrays.asList(new String[]{dozerMappingfile}));
2) Covert each object to a normal object removing persistentbag related details
List<MyEjb> lstProfilehib = //hibernate loaded objects
List<MyEjb> lstProfile = new ArrayList<MyEjb>();
for(MyEjb sp: lstProfilehib){
lstProfile.add( dtoMapper.map(sp, MyEjb.class));
}
Related
I am implementing a form of CQRS that uses a single data store but separate Query and Command models. For the command side of things I am implementing DDD including Repositories, IoC and Dependency Injection. For the Query side I am using the Finder pattern as described here. Basically, a finder is similar to a Repository, but with Find methods only.
So in my application for the read side, in my DAL, I use ADO.net and raw SQL to do my queries. The ADO.Net stuff is all abstracted away into a nice helper class so that my Finder classes simply pass the query to the ADO helper which returns generic data objects which the finder/mapper class turns into read models.
Currently the Finder methods, like my command repositories, are accessed through interfaces that are injected into my controllers, but I am wondering if the interfaces, DI and IoC are overkill for the query side, as everything I have read about the read side of CQRS recommends a "thin data layer".
Why not just access my Finders directly? I understand the arguments for interfaces and DI. ie Separation of Concerns and testability. In the case of SOC, my DAL has already separated out database specific logic by using a mapper class and putting the ADO.net stuff in a helper class. As far as testing is concerned, according to this question unit testing read models is not a necessity.
So in summary, for read models, can I just do this:
public class PersonController : Controller
{
public ActionResult Details(int id)
{
var person = new Person();
person = PersonFinder.GetByID(id);
// TODO: Map person to viewmodel
return this.View(viewmodel);
}
}
Instead of this:
public class PersonController : Controller
{
private IPersonFinder _person;
public PersonController(IPersonFinder person)
{
_person = person;
}
public ActionResult Details(int id)
{
Person person = _person.GetByID(id);
// TODO: Map person to viewmodel
return this.View(viewmodel);
}
}
Are you using both IoC and DI? That's bad ass! Anyways, the second version is the better one because it doesn't depend on a static class. Using statics will open Pandora's box, don't do it, for all the reasons that using static is bad.
You really don't get any benefits for using a static class and once you are already using a DI Container, there's no additional cost. And you are using the Finders directly but you let the DI Container instantiate one instead of you calling a static object.
Update
A thin read layer refers to using a simplified read model instead of the rich domain objects. It is unrelated to DI, it doesn't matter how the query service is built or by whom, it matters to not involve the business objects in queries.
Read/Write separation is completely unrelated to coding techniques like dependency injection. Your read models are serving fewer purposes than your combined read/write models were before. Could you consider ditching all the server-side code and just using your database's native REST API? Could you wire your controller to directly query the database with SQL and return the data as JSON? Do you need a generic repository-like pattern to deal with specific read requests?
I am new to entity framework and mvc.
I am trying to understand what a Controller should pass to the view.
Should it be the class from Models (MySolution.Models.Story) or the class from the entity framework (MySolution.Story).
The problem is that if I pick the one from entity framework, then the DataTypes and html-helpers are not working correctly. If I pick the class from models, then I can't convert from the entity class to the model class, for example:
TrendEntities TrendDB = new TrendEntities();
public ActionResult Details(int id) {
var Country = TrendDB.Countries.FirstOrDefault(c => c.CountryId ==id);
return View(Country);
}
Just use the adp.net entity framework POCO templates to generate. download the template. right click in the entity designer and select "add code generation item" and choose the poco template. Now your objects dont have all of the 'entity framework baggage' with them. Proxies are automatically created behind the scenes and you don't need to do any object mapping.
You can find this template by adding a new item to visual studio 2010, and searching the online templates from within the add dialog for POCO. The template name is:
ADO.NET C# POCO Entity Generator
You are looking for either AutoMapper or ValueInjecter. These two libraries are "Object to Object" mappers, which are designed for mapping values from one object to another object. I have only used AutoMapper before. It is great and pretty easy to pick up. I've heard good things about ValueInjecter as well.
After some investigation, I figured out that I had a design problem.
Long story short, REMEMBER that in MVC 3 we need a to define the following class in the model
public class StoryDBContext : DbContext
{
public DbSet<Story> Stories {get; set;}
}
And then in the controller THAT's the one to use when accessing the Entity Framework.
In the previous version we were not defining the above class and were using the TrendEntities class (that was created by the framework) to access the DB.
That's a bit confusing...
So, in my example, TrendDB should be of type StoryDBContext instead of TrendEntities and things are working as expected.
Use a ViewModel. This is a class that you declare having the properties you want to display on your View.
For example:
var country = TrendDB.Countries.FirstOrDefault(c => c.CountryId == id);
CountryDetails details = new CountryDetails();
details.FirstValueToShow = country.Name;
return View(details);
Remember to strongly type your Details view to the ViewModel.
How do bind my domain object Car to View?
MVC says "your class must have default constructor". But I don't want to change any business rules by creating a default constructor. The only solution I can see - is to use CarView in my View and then map it to Car.
P.S. NHibernate wants a default constructor too, but it can be protected. This I can do.
IMHO, its a good idea to seperate the objects that go to your view from you domain objects. This has a long list of advantages (which I am not going into now).
You can then use Automapper to map your view models to your domain objects
You could create the object yourself and call UpdateModel to do the binding instead:
public ActionResult MyAction()
{
var car = new MyCar(somethingToPassIntoTheConstructor);
UpdateModel(car);
// Do stuff with car.
}
I've got a number of tables in my db that share common cols: modified by, modified date, etc. Not every table has these cols. We're using LINQ to Enties to generate the
I'd like to create a custom binder class that can handle the automatic binding of these fields. Is there a way to do this without having a custom binding class for each entity class?
Here's the code I have:
In global.asax.cs, Application_Start():
ModelBinders.Binders.Add(typeof(Foo),new FooBinder());
Then in FooBinder.cs:
public override Object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var obj = (Foo)base.BindModel(controllerContext, bindingContext);
var user = controllerContext.HttpContext.User.Identity;
obj.modified_by = user.Name;
obj.modified_date = DateTime.Now;
return obj;
}
Is there a way to generalize this so it can handle multiple types?
We do this in the repository, not in the binder. We have an interface with the common fields (Modified on). We implement the interface in partial classes which we codegen for our entities using a T4 template.
You can use reflection to set fields by name, so that you can do foreach over property names. This is not a big deal since model binder uses reflection itself to get to the properties, anyway. Then you can just register binder for each of the "common" types - which is also OK to do using reflection, for example by checking that entity has all fields required present - so it works even if you add new such entities.
Just have your binder call default one and then update the fields.
In my ASP MVC application I'm using standard SQL (rather that Linq to SQL or other ORM) to query my database.
I would like to pass the database results to my view and iterate over the results in my view. But I'm not sure how to do this. Every example I've seen passes some string or uses L2S. I would like to pass something like nested Hashtables, but the only thing I can think of is to pass an SqlDataReader object to the view, but this sounds like a really bad idea.
How would I go about displaying my database results from a standard SQL query to my view? I would really like use Linq or other ORM, but requirements dictate we don't (don't ask me why, I don't understand). I'm doing this in VB. I'll try by best to convert any C# examples provided.
You could create simple classes for the data you want to transfer and then populate a List of objects in your controller from a data reader manually, and then pass this to your View - e.g. (C# but this should be easy to convert)
// open your connection / datareader etc.
List<Customer> customers = new List<Customer>();
while(dataReader.Read())
{
Customer c = new Customer();
c.Id = dataReader.GetInt32(0);
c.Name = dataReader.GetString(1);
// etc (you might want to use string indexers instead of ints for the get methods)
customers.Add(c);
}
// close and dispose your datareader / connection etc as usual
return View("List", customers);
MVC is about separation of concerns. Passing SqlDataReaders, DataTables, or whatever class that resides in the System.Data namespace to a view is not a good idea. You need to define a model which might talk to the database, and a controller which will pass this model to the view. If your company policy says don't use an ORM then maybe classic WebForms are better suited to your scenario than the MVC pattern.
I agree with Rashack. This article explains it in some detail.link text
In a nutshell, here's how to do it using DataTable and DataReader:
private DataTable GetData()
{
DataTable dt = new DataTable();
using (SqlConnection connection
= new SqlConnection("ConnectionString"))
using (SqlCommand command = new SqlCommand())
{
command.Connection = connection;
command.CommandText = "SELECT * FROM Customers";
connection.Open();
using (SqlDataReader reader =
command.ExecuteReader
(CommandBehavior.CloseConnection))
{
dt.Load(reader);
}
}
return dt;
}
Then, you can read that DataTable into an entity object that you pass around.
I think you'll find this can yield much better performance than using Linq or an ORM.
Try using DataTables - DataTable can load data from IDataReader... (I think the method's called Load)
You could create your own Data Transfer Object classes and populate instances of them using ADO.Net code. These DTO classes would be simple POCO-style classes that just contained property get/set accessors, no methods. Using POCO objects is arguably preferable to DataSets/DataTables as they are lightweight (no superfluous state) and are more intuitive to work with from an object-oriented perspective.