Best practises for integrating with

126 views
Skip to first unread message

sigusr

unread,
Feb 27, 2011, 5:51:11 PM2/27/11
to S#arp Architecture
Now that I have a basic project modelled around S#arp I'm looking to
start building an actual web application.

Are there any recommended methods for creating nice web forms and data
grids with S#arp? This is my first foray into ASP with MVC and
nhibernate, so I am starting from scratch with no requirement to port
old code.

Right now I just need:

- decent display of tabular data (I could hack up my own tables, but
I'm sure there are better alternatives)
- decent forms with validation support (linked to the model would be
great)

I see a myriad of ways of doing these on the official ASP.NET site but
many revolve around Linq or situations where the database is very
tightly coupled to the model.

In the long run it would be great to integrate some basic Ajax
functionality too (such as search or field completion) so options for
this would be good.

Suggestions for what to look at or what to avoid would be appreciated.

Alec Whittington

unread,
Feb 27, 2011, 6:48:10 PM2/27/11
to sharp-arc...@googlegroups.com

Take a look at mvccontrib as well as telerik mvc. I've used both and like both. Telerik is based on jquery, easy to use, and easily customizable.

> --
> You received this message because you are subscribed to the Google Groups "S#arp Architecture" group.
> To post to this group, send email to sharp-arc...@googlegroups.com.
> To unsubscribe from this group, send email to sharp-architect...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/sharp-architecture?hl=en.
>

sigusr

unread,
Mar 11, 2011, 10:29:42 AM3/11/11
to S#arp Architecture
I am now using the Telerik grid. It works great when data is bound by
the server and the page can refresh every time it needs to update.
However, this relies on my GetAll() method (therefore hits the whole
DB table) and doesn't use Ajax (which is required for some partial
views) so I'd like to start using client binding with Ajax.

By the looks of it, only Linq is supported. Has anybody managed to
implement client binding with the Telerik grid in a S#arp application?

Thanks,

David



On Feb 27, 11:48 pm, Alec Whittington <alec.whitting...@gmail.com>
wrote:

Lucas Barlassina

unread,
Mar 11, 2011, 10:38:18 AM3/11/11
to sharp-arc...@googlegroups.com
I'm using Telerik grid with client binding and sharparch 1.6 without
problems.
What version are you using?

-----Mensaje original-----
De: sharp-arc...@googlegroups.com
[mailto:sharp-arc...@googlegroups.com] En nombre de sigusr
Enviado el: viernes, 11 de marzo de 2011 01:30 p.m.
Para: S#arp Architecture
Asunto: Re: Best practises for integrating with

Ryan Barrett

unread,
Mar 11, 2011, 10:42:07 AM3/11/11
to sharp-arc...@googlegroups.com

You need to implement the (linq) specification pattern and translate the telerik filter to that.

sigusr

unread,
Mar 11, 2011, 11:02:25 AM3/11/11
to S#arp Architecture
I am using 1.9.5, so if it works for you then it should work for me.

If you are using it successfully Lucas, can you advise whether you
simply implemented it like the demo at http://demos.telerik.com/aspnet-mvc/razor/grid/custombinding
or whether you had to do something different?

I haven't looked at using Linq at all with NHibernate or S#arp yet.


On Mar 11, 3:42 pm, Ryan Barrett <r...@seldonplan.com> wrote:
> You need to implement the (linq) specification pattern and translate the
> telerik filter to that.

Alec Whittington

unread,
Mar 11, 2011, 11:17:48 AM3/11/11
to sharp-arc...@googlegroups.com
I'm using it with S# 1.0 and have no issues at all. You do not need to use GetAll - use your own method that returns IQueryable that you can then use Take and Skip to limit your results as well as page.

alec

sigusr

unread,
Mar 11, 2011, 11:43:02 AM3/11/11
to S#arp Architecture
I can see in theory how that would work. Does your method return an
IQueryable of a DTO or the actual domain model?

If you have a small snippet of example code that works for you I'd
appreciate it.


On Mar 11, 4:17 pm, Alec Whittington <alec.whitting...@gmail.com>
wrote:

Lucas Barlassina

unread,
Mar 11, 2011, 12:02:36 PM3/11/11
to sharp-arc...@googlegroups.com
Is very simple, try do it on a clean new page.... with a simple test... The
key is to make the call on ".Select(......url)"
I use ajax Binding, not custom Binding.

This is a sample, from an Animals Grid...
VIEW:
<div id="gridRegion">
<% Html.Telerik().Grid<ActiveAnimalRow>()
.Name("ActiveAnimalGrid")
.DataBinding(dataBinding => dataBinding
//Ajax binding
.Ajax()
//The action method which will return JSON
.Select("ActiveGrid", "Animals", new { dairyId =
Model.CurrentDairy })
)
.Columns(colums =>
{
colums.Bound(b => b.Identification)
.Title("RP")
.ClientTemplate("<#= IdentificationTemplate #>")
.Width(5)
.Filterable(true);
})
.Pageable(pager => pager.PageSize(20))
.Sortable()
.Selectable()
.Filterable()
.Render();
%>
</div>


CONTROLLER (AnimalsController):
[GridAction]
public ActionResult ActiveGrid(int dairyId)
{

var animals = this.dairyAnimalService.GetActiveAnimals(dairyId,
DateTime.Now);

var rows = GetRows<ActiveAnimalRow>(animals);
// retorno la vista
return View(new GridModel(rows));
}

-----Mensaje original-----
De: sharp-arc...@googlegroups.com
[mailto:sharp-arc...@googlegroups.com] En nombre de sigusr

Enviado el: viernes, 11 de marzo de 2011 02:02 p.m.

Alec Whittington

unread,
Mar 11, 2011, 12:03:26 PM3/11/11
to sharp-arc...@googlegroups.com
I return the object - do not return IQueryable as it might cross a service boundary and not work. That object will then get mapped into a ViewModel along with the other pieces needed for the view.

Alec

sigusr

unread,
Mar 11, 2011, 5:33:09 PM3/11/11
to S#arp Architecture
Alex and Lucas, thanks. I understand the client binding and
controller side of things, but I don't understand the LINQ portion at
all. I assume your dairyAnimalService.GetActiveAnimals is returning
an IQueryable. I haven't used LINQ at all with NHibernate at all.
Could you show how your GetActiveAnimals works and what it returns?

Many of the pages I find relate to 2008/2009. I will check
WhoCanHelpMe too, as I know that uses it.

Thanks again for your help.


On Mar 11, 5:03 pm, Alec Whittington <alec.whitting...@gmail.com>

Alec Whittington

unread,
Mar 11, 2011, 6:04:24 PM3/11/11
to sharp-arc...@googlegroups.com
No worries - we all try to help as we can, when we can.

When I use IQueryable in the Repositories, I always return the real object. I know plenty of others that return IQueryable, but I am not a huge fan of that. 

Alec

Lucas Barlassina

unread,
Mar 11, 2011, 9:30:31 PM3/11/11
to sharp-arc...@googlegroups.com
I do not return an IQueryable... note that the GridModel expect an
IEnumerable... so GetActiveAnimals returns an IList of the DTO


-----Mensaje original-----
De: sharp-arc...@googlegroups.com
[mailto:sharp-arc...@googlegroups.com] En nombre de sigusr
Enviado el: viernes, 11 de marzo de 2011 08:33 p.m.

Para: S#arp Architecture
Asunto: Re: Best practises for integrating with

Alex and Lucas, thanks. I understand the client binding and

sigusr

unread,
Mar 12, 2011, 7:51:59 AM3/12/11
to S#arp Architecture
OK, this is the bit I am getting confused about.

Are you simply returning all active animals (for the given dairy and
date/time) from GetActiveAnimals and letting GetRow handle pagination/
ordering/etc?

I was imagining that somehow you were limiting the amount of rows
selected, to decrease the hit on the database. If you are just
relying on GetRow handling the hard work (rather than the querying)
then that's fine, I understand it. That's exactly how my current
method works, only I bind the data on the server rather than via.
Ajax.

If not, I'm missing something major and it's probably voodoo magic!

Alec Whittington

unread,
Mar 12, 2011, 8:38:44 AM3/12/11
to sharp-arc...@googlegroups.com
The telerik grid has ajax capability. It will use an action method on your controller that passes in a GridCommand among other items (you can pass in as well). This GridCommand contains the PageSize and which PageNumber you are on. When my Controller receives this call, I pass only those two items from it to my service. The service returns an IEnumerable<T> of my entity from my repository. The repository gets this by code looking like this:

var query = (from e in Session.Linq<MyEntity> select e).AsQueryable();
return query.Skip((Page - 1) * PageSize).Take(PageSize).ToList();

In my controller, I then map the IEnumerable<T> into my GridModel for the grid. You never want to return all, then let the Grid do it's magic. Can you imagine a table of even 1000 rows with a heavy object graph and lazy-load off? This would mean each would have it's complete object graph loaded, then it would Take and Skip what it needed. The way I listed above would generate a sql statement that would give you only what you need.

Hope that helps
Alec

Ryan Barrett

unread,
Mar 12, 2011, 1:14:42 PM3/12/11
to sharp-arc...@googlegroups.com
Alec, are you using the grid's filtering or sorting?  Because skip/take only give you paging of a list.  You need to do a little more work if you'd also like to filter the contents of the list, or offer different sorting options.

In that situation you need to pull "filter" from the querystrings and turn it into some sort of specification (or directly into a Linq statement)

I think you might have posted this link before, but here's a thread explaining it on telerik.com.


Doing this is on my own todo list.  Gotta write a parser to parse the telerik format and turn it into a LINQ specification for my project.  If I can get a couple of free days to implement it I'll see if it can be added to the contrib project.  Seems to be something lots of others could use too...

-- 
Ryan

Zac

unread,
Mar 12, 2011, 2:17:12 PM3/12/11
to S#arp Architecture
I would also find a parser for telerik like that very useful.

On Mar 12, 10:14 am, Ryan Barrett <r...@seldonplan.com> wrote:
> Alec, are you using the grid's filtering or sorting?  Because skip/take only
> give you paging of a list.  You need to do a little more work if you'd also
> like to filter the contents of the list, or offer different sorting options.
>
> In that situation you need to pull "filter" from the querystrings and turn
> it into some sort of specification (or directly into a Linq statement)
>
> I think you might have posted this link before, but here's a thread
> explaining it on telerik.com.
>
> http://www.telerik.com/community/forums/aspnet-mvc/grid/example-of-cu...
>
> Doing this is on my own todo list.  Gotta write a parser to parse the
> telerik format and turn it into a LINQ specification for my project.  If I
> can get a couple of free days to implement it I'll see if it can be added to
> the contrib project.  Seems to be something lots of others could use too...
>
> --
> Ryan
>

Alec Whittington

unread,
Mar 13, 2011, 6:25:11 PM3/13/11
to sharp-arc...@googlegroups.com

Ryan,
    I'm using filtering and sorting as well. Everything is coming over in the grid command. I am using a very early release of telerik.
Alec

Christian Setzkorn

unread,
Mar 14, 2011, 5:44:59 AM3/14/11
to sharp-arc...@googlegroups.com
Hi,

I used to use ICriteria for filtering etc.:

http://stackoverflow.com/questions/4614430/generic-data-grid-filtering

(not sure whether the code sample is exhaustive enough?)

However I have recently found that lucene.net is really good for filtering. This link shows you how to integrate nhibernate search into s#arp:

http://wiki.sharparchitecture.net/%28S%28msyair55gxqvym2ygwsgvxrj%29%29/Default.aspx?Page=NHibSearch&AspxAutoDetectCookieSupport=1

It is really easy to use lucene.net. You would have methods like the ones below in your repository (not sure whether the others aggree?). I have not used telerik for ages but what comes from the frontend needs to be parsed into a suitable 'term' (see Query method below). The book 'Lucene in action' is really useful if you want to learn about lucene quickly. Hope this helps somehow.

Christian

public void BuildSearchIndex()
        {
            FSDirectory entityDirectory = null;
            IndexWriter writer = null;

            var entityType = typeof(MappedSequence);

            var indexDirectory = new DirectoryInfo(GetIndexDirectory());

            if (indexDirectory.Exists)
            {
                indexDirectory.Delete(true);
            }

            try
            {
                entityDirectory = FSDirectory.Open(new DirectoryInfo(Path.Combine(indexDirectory.FullName, entityType.Name)));
                writer = new IndexWriter(entityDirectory, new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29), true, IndexWriter.MaxFieldLength.UNLIMITED);
            }
            finally
            {
                if (entityDirectory != null)
                {
                    entityDirectory.Close();
                }

                if (writer != null)
                {
                    writer.Close();
                }
            }

            IFullTextSession fullTextSession = Search.CreateFullTextSession(this.Session);
            // Iterate through Suppliers and add them to Lucene's index
            foreach (MappedSequence instance in Session.CreateCriteria(typeof(MappedSequence)).List<MappedSequence>())
            {
                fullTextSession.Index(instance);
            }
        }

        private string GetIndexDirectory()
        {
            INHSConfigCollection nhsConfigCollection = CfgHelper.LoadConfiguration();
            string property = nhsConfigCollection.DefaultConfiguration.Properties["hibernate.search.default.indexBase"];
            var fi = new FileInfo(property);
            return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fi.Name);
        }

        public IList<MappedSequence> Query(string term, out int total, int page, int pageSize)
        {
            if (term.ToString().Equals("") == false)
            {
                var parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_29, new[] { "Query" }, new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29));
                Query query = parser.Parse(term);

                IFullTextSession session = Search.CreateFullTextSession(this.Session);
                IQuery fullTextQuery = session.CreateFullTextQuery(query, new[] { typeof(MappedSequence) });
                total = fullTextQuery.List<MappedSequence>().Count();
                return fullTextQuery.List<MappedSequence>().Skip((page - 1) * pageSize).Take(pageSize).ToList<MappedSequence>();
            }
            else
            {
                total = 0;
                return null;
            }
        }

Seif Attar

unread,
Mar 14, 2011, 2:42:37 PM3/14/11
to sharp-arc...@googlegroups.com
We've using the WcfSessionStorage on a couple of project without a problem. If I remember correctly, for WcfStorage the session is stored in OperationContext, which will get cleared out when the request ends.

On Mon, Mar 14, 2011 at 6:12 PM, Lucas Barlassina <lbarl...@gmail.com> wrote:
I found a problem on SharpArch 1.6 on wcfsessionStorage..
Here is my problem:

On  WebSessionStorage
When a request Ends.. This happens
               private void Application_EndRequest(object sender, EventArgs
e)
           {
                 NHibernateSession.CloseAllSessions();

                 HttpContext context = HttpContext.Current;
               context.Items.Remove(HttpContextSessionStorageKey);
           }

       So in new Request new SimpleSessionStorage() comes

On WcfSessionStorage
       the session is closed at: DispatchMessageInspector

               public void BeforeSendReply(ref Message reply, object
correlationState)
           {
                 NHibernateSession.CloseAllSessions();
           }
THE Session is simply closed, not Cleaned its StorageManager. So when a new
request comes, returns the session closed.

Anybody experimente the same problem?
I cannot use a wcf proxy client twice....

For now my simple solution is the next:
In class SessionInstanceExtension. change this

public ISession GetSessionForKey(string factoryKey)
           {
           //return storage.GetSessionForKey(factoryKey);

           var session = storage.GetSessionForKey(factoryKey);
           if (session != null && session.IsOpen == false)
           {
               storage.SetSessionForKey(factoryKey, null);
               session = null;
           }
           return session;

Lucas Barlassina

unread,
Mar 14, 2011, 2:12:16 PM3/14/11
to sharp-arc...@googlegroups.com

Matt

unread,
Aug 2, 2013, 9:24:50 AM8/2/13
to sharp-arc...@googlegroups.com
Lucas

I'd like to thank you for this post - it has saved me a lot of time. Shame you didn't have any recognition sooner because others must have been pulling their hair out. I've seen people using ThreadSessionStorage instead of the WcfSessionStorage!

Thank you!
Matt

Lucas Barlassina

unread,
Aug 2, 2013, 9:39:49 AM8/2/13
to sharp-arc...@googlegroups.com

Thanks!

--

You received this message because you are subscribed to the Google Groups "S#arp Architecture" group.

To unsubscribe from this group and stop receiving emails from it, send an email to sharp-architect...@googlegroups.com.


To post to this group, send email to sharp-arc...@googlegroups.com.

Reply all
Reply to author
Forward
0 new messages