Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

MonoRail

0 views
Skip to first unread message

Peter Morris

unread,
Jan 30, 2008, 11:41:04 AM1/30/08
to

John Moshakis

unread,
Jan 30, 2008, 1:57:01 PM1/30/08
to
Peter Morris wrote:

> http://mrpmorris.blogspot.com/2008/01/monorail.html

Hi Peter,

Thats cool. I don't suppose you could provide an example with that ? I
was also wondering if you had thought about using an mvc pattern with
webforms and discarded it for some reason ?

Cheers,
John

--

Peter Morris

unread,
Jan 30, 2008, 2:41:10 PM1/30/08
to
Framework so far is in attachements.

Steps

01: Create a MonoRail website
02: Create an EcoWebsite into a different folder.
03: Copy all the ECO stuff into the MR folder except the website.

Then you can do this....


public class ProductController : EcoSmartDispatcherController
{
[UseEcoSpaceSession(Eco.Web.EcoSpaceStrategyHandler.SessionStateMode.IfDirty)]
public void Create()
{
PropertyBag["Product"] = new
Product(GetEcoSpace<InteevoWebsiteEcoSpace>());
}

[UseEcoSpaceSession(Eco.Web.EcoSpaceStrategyHandler.SessionStateMode.IfDirty)]
public void Create([EcoDataBind(typeof(InteevoWebsiteEcoSpace),
"Product")]Product product)
{
PropertyBag["Product"] = product;
}
}


with your view looking like this (if you use Brail as I did).

${HtmlHelper.Form('create.rails')}
${EcoFormHelper.ExternalId('Product', Product)}
Name : ${HtmlHelper.InputText('Product.Name', Product.Name)}<br/>
Current version number :
${HtmlHelper.InputText('Product.CurrentVersionNumber',
Product.CurrentVersionNumber)}<br/>
${HtmlHelper.SubmitButton('Save')}
${HtmlHelper.EndForm()}


I am not sure that I will keep the special controller class. Tomorrow I
will be looking at Inversion of Control to see if that helps.


Pete


Dmitriy Nagirnyak

unread,
Jan 30, 2008, 6:42:43 PM1/30/08
to
Hello Peter,

> http://mrpmorris.blogspot.com/2008/01/monorail.html
>
Great work done!


Just curious, why did you choose Brail? NVelocity looks like more populare
and has more sample.


Some comments:
==============================================
EcoDataBinder:
==============================================
It requires typeof(EcoSpace) parameter.
Also UseEcoSpacePool requres the same parameter.

I just think it would be nice not to repeat every time the EcoSpace type
in EcoDataBind and use the one defined on method or class.
But leave it as optional.
For example:
public void Create(
[EcoDataBind(typeof(MyEcoSpace), "Product", CreateIfNoObjectId=true)]Product
product,
[EcoDataBind(typeof(YourEcoSpace), "Customer", CreateIfNoObjectId=true)]Customer
customer)
{
PropertyBag["Product"] = product;
PropertyBag["Customer"] = product;
}

Doesn't look good. Two objects from different EcoSpace.

I think probably in most cases EcoSpace type will be the same within method/class.
So the syntaz would look better like this:
[UseEcoSpacePool(typeof(MyEcoSpace), false)]
public class ProductController
{
public void Create(
[EcoDataBind(NoObjectAction=NoObjectAction.Create)]Product product,
[EcoDataBind]Customer customer)
{
PropertyBag["Product"] = product;
PropertyBag["Customer"] = product;
}
}


===
Notice here:
1. No EcoSpace type in EcoDataBind.
2. No binding Prefix (eg: Product). Let it use the parameter name, if it
is not specified (product).
3. Replace CreateIfNoObjectId to enum NoObjectAction={Ignore, Create, Error}.
Default is Ignore. See below why.


I also see another things to improve.
=================================================================================

Let's say we have someway (hack or just some mistake) this field with ExternalId:
<input type="hidden" name="product.ExternalId" value="really-invalid-ID" />

So when it will be binded to a real product it will return throw an exception
from IExternalIdService or will return a "half-valid" object.
This object can be used but has Deleted status.

This opens some holes:
1. Easily fail the site with putting some invalid IDs.
2. Using invalid objects.

======Proposition:
Change code EcoDataBinder from line 44 to something like this:
try
{
IExternalIdService externalIdService = EcoServiceHelper.GetExternalIdService(EcoSpace);
IObjectInstance obj = externalIdService.ObjectForId((string)externalIdNode.Value);
if (obj.AsObject != null && obj.Deleted)
return null;
return obj;
}
catch (WhatToCatchHere??-Probably all)
{
return null;
}

=========================================================================
Also line 40 should not raise an error by default, but return null.
This is because of this:
<input type="hidden" name="Somebody-Changed-it-on-client-product.ExternalId"
value="really-invalid-ID" />

I don't want it was raising an error on the site, but you might want.

======= Proposition:
Replace CreateIfNoObjectId to enum NoObjectAction.
NoObjectAction is used when there is no ExternalId, object or some node found.

- Ignore - no errors produced, should safely return NULL (Default).
- Create - creates a new object.
- Error - throws an exception.

=========================================================================


Ok. I think that's it for now.
What do you think about all that?


BTW, do you plan to put the code somewhere on CodePlex or Google Code?

Cheers,
Dmitriy Nagirnyak
http://dcportal.argocomputing.com.au
http://dnagir.blogspot.com


Peter Morris

unread,
Jan 31, 2008, 4:15:24 AM1/31/08
to
Apparently Brail allows OOP, so I thought I'd give it a try just in case I
needed it :-)

> public void Create(
> [EcoDataBind(typeof(MyEcoSpace), "Product",
> CreateIfNoObjectId=true)]Product product,
> [EcoDataBind(typeof(YourEcoSpace), "Customer",
> CreateIfNoObjectId=true)]Customer customer)
> {
> PropertyBag["Product"] = product;
> PropertyBag["Customer"] = product;
> }
> Doesn't look good. Two objects from different EcoSpace.

The ability is there, doesn't mean you have to use 2 different EcoSpaceTypes
:-)


> I think probably in most cases EcoSpace type will be the same within
> method/class. So the syntaz would look better like this:
> [UseEcoSpacePool(typeof(MyEcoSpace), false)]
> public class ProductController
> {
> public void Create(
> [EcoDataBind(NoObjectAction=NoObjectAction.Create)]Product product,
> [EcoDataBind]Customer customer)
> {
> PropertyBag["Product"] = product;
> PropertyBag["Customer"] = product;
> }
> }
>
>
> ===
> Notice here:
> 1. No EcoSpace type in EcoDataBind.

Which means I cannot determine which type of eco space to create an instance
of to get the object from. Maybe I could add a
[DefaultEcoSpaceType(typeof(X))]

> 2. No binding Prefix (eg: Product). Let it use the parameter name, if it
> is not specified (product).

It's the name use in the html, e.g.

<input name="Product.Name"/>
<input name="Product.VersionNumber"/>

It can't be optional because it is mandatory in MR. MR sees Product.* and
realises that they are all a single entity.


> 3. Replace CreateIfNoObjectId to enum NoObjectAction={Ignore, Create,
> Error}. Default is Ignore. See below why.

I did have AutoCreateBehavior=AutoCreateBehaviour.FetchOnly/Create but it is
long winded.

> Let's say we have someway (hack or just some mistake) this field with
> ExternalId:
> <input type="hidden" name="product.ExternalId" value="really-invalid-ID"
> />
>
> So when it will be binded to a real product it will return throw an
> exception from IExternalIdService or will return a "half-valid" object.
> This object can be used but has Deleted status.

I will have to test it.

>
> This opens some holes:
> 1. Easily fail the site with putting some invalid IDs.
> 2. Using invalid objects.
>
> ======Proposition:
> Change code EcoDataBinder from line 44 to something like this:
> try
> {
> IExternalIdService externalIdService =
> EcoServiceHelper.GetExternalIdService(EcoSpace);
> IObjectInstance obj =
> externalIdService.ObjectForId((string)externalIdNode.Value);
> if (obj.AsObject != null && obj.Deleted)
> return null;
> return obj;
> }
> catch (WhatToCatchHere??-Probably all)
> {
> return null;
> }

I think that checking for deleted is a good idea, I will add that.


> =========================================================================
> Also line 40 should not raise an error by default, but return null.
> This is because of this:
> <input type="hidden"
> name="Somebody-Changed-it-on-client-product.ExternalId"
> value="really-invalid-ID" />
>
> I don't want it was raising an error on the site, but you might want.
>
> ======= Proposition:
> Replace CreateIfNoObjectId to enum NoObjectAction.
> NoObjectAction is used when there is no ExternalId, object or some node
> found.
>
> - Ignore - no errors produced, should safely return NULL (Default).
> - Create - creates a new object.
> - Error - throws an exception.
>
> =========================================================================
>
>
> Ok. I think that's it for now.
> What do you think about all that?

Due to the fact that the binding occurs before the method is called you
cannot trap it yourself. I need to check what happens really. Have you
tried it?


> BTW, do you plan to put the code somewhere on CodePlex or Google Code?

At the moment I have no idea what I am going to do other than to make it
public :-)


Pete


Dmitriy Nagirnyak

unread,
Jan 31, 2008, 6:20:12 AM1/31/08
to
Hello Peter,

> Apparently Brail allows OOP, so I thought I'd give it a try just in
> case I needed it :-)
>

Ok. Just trying...
I think NVelocity syntax is a bit simpler for the View.
Brail might be much more powerful, but I don't think the View needs some
OOP stuff.
Anyway it seems Brail is 2nd popular in MonoRail area, so there must be reasons
for that too.

The ASPX view's syntax is horrable for me. To many syntax construction for
simple things.

>> [UseEcoSpacePool(typeof(MyEcoSpace), false)]
>> public class ProductController
>> {
>> public void Create(
>> [EcoDataBind(NoObjectAction=NoObjectAction.Create)]Product product,
>> [EcoDataBind]Customer customer)
>> {
>> PropertyBag["Product"] = product;
>> PropertyBag["Customer"] = product;
>> }
>> }
>> ===
>> Notice here:
>> 1. No EcoSpace type in EcoDataBind.
> Which means I cannot determine which type of eco space to create an
> instance of to get the object from. Maybe I could add a
> [DefaultEcoSpaceType(typeof(X))]
>

Yes. That's exactly what I mean.

I mean there should not be too many attributes each with typeof(MyEcoSpace).
This doesn't look good for me:

[DefaultEcoSpaceType(typeof(X))]
[UseEcoSpacePool(typeof(X), true)]
public class XxxController : YyyBaseController
{
}


What for actually are those attributes? They are to:
1. Define EcoSpace type to be used.
2. Define how/where to retrieve EcoSpace.
3. Define how/where to return EcoSpace.


All these 3 items seems to cover all the MR-EcoSpace stuff.
All of the 3 items might be user defined with one attribute, like this:

EcoSpaceHandler(Type=typeof(MyEcoSpace), RetrieveType=typeof(SessionFreeNoPoolGetter),
ReturnType=typeof(JustDestroyEcoSpace))
This is very customaziable attribute.
If you need something non-standard, put you type there.
For standard situation there might be something like this:
EcoSpaceHandler(Type=typeof(MyEcoSpace), RetrieveType=typeof(DefaultPoolableRetriever),
ReturnType=typeof(DefaultPoolableReturenr))
etc, etc.

Or just simplified version:
PoolableEcoSpaceHandler(Type=typeof(MyEcoSpace))
RequestOnlyEcoSpaceHandler(Type=typeof(MyEcoSpace))
SessionAwareEcoSpaceHandler(Type=typeof(MyEcoSpace))
etc


>> 2. No binding Prefix (eg: Product). Let it use the parameter name, if
>> it is not specified (product).
>>
> It's the name use in the html, e.g.
>
> <input name="Product.Name"/>
> <input name="Product.VersionNumber"/>
> It can't be optional because it is mandatory in MR. MR sees Product.*
> and realises that they are all a single entity.

Yes. I know.
But I mean other.
Saying "No binding Prefix" I mean there's no need to specify it in the EcoDataBinder.
If it is not specified the parameter name should be used instead (eg: product).
This simplifies syntax avoiding name dublicates.

This is what I would like to write for my Controller/Action:

PoolableEcoSpaceHandler(Type=typeof(MyEcoSpace))
public class ProductController : BlaBla


{
public void Create([EcoDataBind(NoObjectAction=NoObjectAction.Create)]Product

product)
{
// product will be binded from <input name="product.ExternalId" ... />
by mehod parameter name
}

>> 3. Replace CreateIfNoObjectId to enum NoObjectAction={Ignore, Create,
>> Error}. Default is Ignore. See below why.
>>
> I did have AutoCreateBehavior=AutoCreateBehaviour.FetchOnly/Create but
> it is long winded.
>

I don't think there should be some problem with it.
It seems like you need to modify a couple of lines of code in the Binder.
(If you'll decide - I still better prefer NoObjectAction name:))


>> So when it will be binded to a real product it will return throw an
>> exception from IExternalIdService or will return a "half-valid"
>> object. This object can be used but has Deleted status.
>>
> I will have to test it.
>

BTW, That's why this is in Mantis:
http://magpie.sytes.net/mantis/view.php?id=238

> Due to the fact that the binding occurs before the method is called
> you cannot trap it yourself. I need to check what happens really.

I don't get what you cannot trap.
It seems clear for me (in a role of a consumer of your code:)):
1. Controller is created.
2. Actions is found. There's a reference to .NET method.
3. Data binding occurs. There everything needed: reference to the .NET method
and the controller instance.

What actually can't you trap?

> Have you tried it?
>
No, I have no opportunity for now. I only have had a look at the code.

Peter Morris

unread,
Jan 31, 2008, 7:53:47 AM1/31/08
to
> The ASPX view's syntax is horrable for me. To many syntax construction for
> simple things.

I am just looking at ASPView now. Well, trying to. Someone at
castleproject has annoyed me! From RC2 to RC3 they have removed the ability
to override Controller.InvokeMethod and Controller.ReleaseResources, and I
need them. So at the moment I no longer have something that works. It's
things like this which make me shake my head and think "I should stick to
what everyone else does, ASP.NET".


>> [DefaultEcoSpaceType(typeof(X))]
>>
> Yes. That's exactly what I mean.
>
> I mean there should not be too many attributes each with
> typeof(MyEcoSpace).
> This doesn't look good for me:
>
> [DefaultEcoSpaceType(typeof(X))]
> [UseEcoSpacePool(typeof(X), true)]
> public class XxxController : YyyBaseController
> {
> }

You can already do this

[UseEcoSpacePool(true)]

etc

You only need the type of the eco space when you want to change the setting
for a specific EcoSpaceType.


> What for actually are those attributes? They are to:
> 1. Define EcoSpace type to be used.
> 2. Define how/where to retrieve EcoSpace.
> 3. Define how/where to return EcoSpace.
>
>
> All these 3 items seems to cover all the MR-EcoSpace stuff.
> All of the 3 items might be user defined with one attribute, like this:
>
> EcoSpaceHandler(Type=typeof(MyEcoSpace),
> RetrieveType=typeof(SessionFreeNoPoolGetter),
> ReturnType=typeof(JustDestroyEcoSpace))

I doubt I will implement that. Although you are free to do it yourself, all
you need is an attribute that implements IEcoSpaceProviderSetting.

>>> 2. No binding Prefix (eg: Product). Let it use the parameter name, if
>>> it is not specified (product).

> Yes. I know.
> But I mean other.
> Saying "No binding Prefix" I mean there's no need to specify it in the
> EcoDataBinder.
> If it is not specified the parameter name should be used instead (eg:
> product).
> This simplifies syntax avoiding name dublicates.

I don't even know at this point if it is possible to get the name of the
parameter you have decorated with a reflection attribute. Besides, I think
that changing the name of the parameter should be independant of the HTML
produced.


>>> 3. Replace CreateIfNoObjectId to enum NoObjectAction={Ignore, Create,
>>> Error}. Default is Ignore. See below why.
>>>
>> I did have AutoCreateBehavior=AutoCreateBehaviour.FetchOnly/Create but
>> it is long winded.
>>
> I don't think there should be some problem with it.
> It seems like you need to modify a couple of lines of code in the Binder.
> (If you'll decide - I still better prefer NoObjectAction name:))

I will think about it, but the enum made the code really long.

>> Due to the fact that the binding occurs before the method is called
>> you cannot trap it yourself. I need to check what happens really.
> I don't get what you cannot trap.
> It seems clear for me (in a role of a consumer of your code:)):
> 1. Controller is created.
> 2. Actions is found. There's a reference to .NET method.
> 3. Data binding occurs. There everything needed: reference to the .NET
> method and the controller instance.
>
> What actually can't you trap?

*I* can trap it. What I was saying is that there is no way to trap it
inside your action implementation because it occurs before your method is
invoked.


Pete


Peter Morris

unread,
Jan 31, 2008, 8:29:38 AM1/31/08
to
I don't have Linux.


frank

unread,
Jan 31, 2008, 8:12:45 AM1/31/08
to
Peter, I read tha MonoRail run over Mono, so I think I can do an app using
monorail and deploy it on linux, do you are testing the combination monorail
+ ecoiv on linux?

regards
Frank

"Peter Morris" <peter[dot]morris(at)capableobjects.com> escribió en el
mensaje news:47a1...@newsgroups.borland.com...

John Moshakis

unread,
Jan 31, 2008, 11:01:48 AM1/31/08
to
Peter Morris wrote:


>
> I am just looking at ASPView now. Well, trying to. Someone at
> castleproject has annoyed me! From RC2 to RC3 they have removed the
> ability to override Controller.InvokeMethod and
> Controller.ReleaseResources, and I need them. So at the moment I no
> longer have something that works.
>

Ahh, that would explain why it wouldn't compile.

Cheers,
John

--

Peter Morris

unread,
Jan 31, 2008, 11:22:41 AM1/31/08
to
The code posted works with RC2.

RC3 breaks it all.

The latest source on SVN fixes it, but stops you from running your web app
created on RC2 or RC3 because they have changed the format of the web.config
and renamed/moved/deleted some classes it refers to. In summary I think
that MonoRail RC3 is the worst release candidate I have ever tried of any
product!

I'm quite stressed :-)


Pete

Dmitriy Nagirnyak

unread,
Jan 31, 2008, 6:09:05 PM1/31/08
to
Hello Peter,

>> The ASPX view's syntax is horrable for me. To many syntax
>> construction for simple things.
>>
> I am just looking at ASPView now. Well, trying to. Someone at
> castleproject has annoyed me! From RC2 to RC3 they have removed the
> ability to override Controller.InvokeMethod and
> Controller.ReleaseResources, and I need them.

I have had a look at this Controller class:
https://svn.castleproject.org/svn/castle/trunk/MonoRail/Castle.MonoRail.Framework/Controller.cs

I suppose it is RC3 (trunk).
It has following public virtual methods that you can easily override:

/// <summary>
/// Performs the specified action, which means:
/// <br/>
/// 1. Define the default view name<br/>
/// 2. Run the before filters<br/>
/// 3. Select the method related to the action name and invoke it<br/>
/// 4. On error, execute the rescues if available<br/>
/// 5. Run the after filters<br/>
/// 6. Invoke the view engine<br/>
/// </summary>
/// <param name="engineContext">The engine context.</param>
/// <param name="context">The controller context.</param>
public virtual void Process(IEngineContext engineContext, IControllerContext
context)


/// <summary>
/// Invoked by the view engine to perform
/// any logic after the view had been sent to the client.
/// </summary>
/// <param name="view"></param>
public virtual void PostSendView(object view)


/// <summary>
/// Performs application-defined tasks associated with freeing, releasing,
or resetting unmanaged resources.
/// </summary>
public virtual void Dispose()

/// <summary>
/// Initializes this instance. Implementors
/// can use this method to perform initialization
/// </summary>
protected virtual void Initialize()


So I think having a deepr look into it you can figure out what what you need.


> So at the moment I no
> longer have something that works. It's things like this which make me
> shake my head and think "I should stick to what everyone else does,
> ASP.NET".
>

In this case maybe you might think about trying MS ASP.NET MVC :-)

>>>> 2. No binding Prefix (eg: Product). Let it use the parameter name,
>>>> if it is not specified (product).
>>>>
>> Yes. I know.
>> But I mean other.
>> Saying "No binding Prefix" I mean there's no need to specify it in
>> the
>> EcoDataBinder.
>> If it is not specified the parameter name should be used instead (eg:
>> product).
>> This simplifies syntax avoiding name dublicates.
> I don't even know at this point if it is possible to get the name of
> the parameter you have decorated with a reflection attribute.

It is.
http://msdn2.microsoft.com/en-us/library/system.reflection.parameterinfo(VS.80).aspx
Use an instance of ParameterInfo to obtain information about the parameter's
data type, default value, and so on.
MethodBase.GetParameters returns an array of ParameterInfo objects representing
the parameters of a method, in order.

So it is possible to do this:
foreach(ParameterInfo paramInfo in method.GetParameters())
{
// bla-bla
}


> Besides, I think that changing the name of the parameter should be
> independant of the HTML produced.
>

Why? If you change parameter from "person" to "user", the view should also
operate with "user".
Abyway, it should use method parameter IF NO PREFIX IS SPECIFIED.
As far as I could see MonoRail uses it actively.

The whole idea around MVC and "Convention over configuration" is writing
less code.


>> (If you'll decide - I still better prefer NoObjectAction name:))
> I will think about it, but the enum made the code really long.
>

Yes. It is long. I think ENUM is needed. But how to shoten it... Maybe just
cut the name :)
Or maybe something like this:
EcoDataBind() = EcoDataBind(NoObjectAction=NoObjectAction.Ignore)
EcoDataBind(RaiseError=true) = EcoDataBind(NoObjectAction=NoObjectAction.Error)
EcoDataBind(AutoCreate=true) = EcoDataBind(NoObjectAction=NoObjectAction.Create)

But what if:
EcoDataBind(AutoCreate=true, RaiseError=true)

Something is wrong with this approach :)

> What I was saying is that there is no way to trap it
> inside your action implementation because it occurs before your method
> is invoked.
>

Sorry, but I still don't get it :)

Peter Morris

unread,
Feb 1, 2008, 3:32:46 AM2/1/08
to
I looked into that stuff. There are methods you can override to allocate
class/method level resources for example but I couldn't find anywhere that
identified a MethodInfo so that I could reflect over it. In the latest
source they have reverted these RC3 changes but you have to create new
projects by hand and I haven't got enough free time to work out how to do
that. For now I will stick with RC2.


Peter Morris

unread,
Feb 1, 2008, 6:40:55 AM2/1/08
to
You can now do this:


[DefaultEcoSpaceType(typeof(MyWebsiteEcoSpace))]
public class BaseController : EcoSmartDispatcherController

or in your controller

public override Type EcoSpaceType
{
get { return typeof(MyWebsiteEcoSpace); }
set { base.EcoSpaceType = value; }
}


as a consequence you may now also do this

public void Modify([EcoDataBind("Product")]Product product)

Additionally options are

NoObjectIdAction = ObjectIdAction.CreateNewInstance / ThrowException /
ReturnNull,
InvalidObjectIdAction=ObjectIdAction.CreateNewInstance / ThrowException
/ ReturnNull,
Allow="FirstName,LastName", //Allows only these items to be set via post
data
Exclude="ID, Password, EmailAddress" //Allows all items *except* these
to be set via post data

The last two prevent people from issuing a custom post specifying items on
the class that were not added to the HTML, they come free with MonoRail.


Let me know if you want an update (skype or email), you will need to use RC2
for now though. I wont update it until the new project wizard works in the
trunk source or they release a new update.

Pete


Dmitriy Nagirnyak

unread,
Feb 2, 2008, 1:25:23 AM2/2/08
to
Hello Peter,

> For now I will stick with RC2.
>

Good luck, Pete!

Hope you'll share your expirience with MonoRail+ECO.

Peter Morris

unread,
Feb 2, 2008, 3:28:01 AM2/2/08
to
Keep an eye on http://mrpmorris.blogspot.com - I'm keeping notes :-)


Dmitriy Nagirnyak

unread,
Feb 2, 2008, 10:53:40 PM2/2/08
to
Hello Peter,

> You can now do this:
>
> [DefaultEcoSpaceType(typeof(MyWebsiteEcoSpace))]
> public class BaseController : EcoSmartDispatcherController
> or in your controller
>
> public override Type EcoSpaceType
> {
> get { return typeof(MyWebsiteEcoSpace); }
> set { base.EcoSpaceType = value; }
> }

I have just got a better idea. Generics.

public class EcoBaseController<TEcoSpace> : EcoSmartDispatcherController
where TEcoSpace : DefaultEcoSpace
{
public virtual TEcoSpace EcoSpace
{ getter and setter here }
}

This way you don't even need to have Type stored somewhere.

For me looks cool. And no any mess with attributes. Usage is simple:
public ProductController : EcoBaseController<MyEcoSpace>
{
public void Modify([EcoDataBind]Product product) {}
}

> Additionally options are
>
> NoObjectIdAction
This is nice.


> Allow="FirstName,LastName", //Allows only these items to be set
> via post
> data
> Exclude="ID, Password, EmailAddress" //Allows all items *except*
> these
> to be set via post data
> The last two prevent people from issuing a custom post specifying
> items on the class that were not added to the HTML, they come free
> with MonoRail.
>

Yes. I know this stuff.
But it really annoys me because of Allow/Exclude are strings.
We'll have to write test to make sure it is working fine (in case property
name is changed).
Why do we need it if in .NET 3.5 it is possible to make it checkable at compile
time...

But this is how MR is working now.


> Let me know if you want an update (skype or email), you will need to
> use RC2 for now though. I wont update it until the new project wizard
> works in the trunk source or they release a new update.
>

I don't need it for now. Just trying to put my 2 cents there to make it better
for you and everybody :)

Dmitriy Nagirnyak

unread,
Feb 2, 2008, 11:54:27 PM2/2/08
to
> Keep an eye on http://mrpmorris.blogspot.com - I'm keeping notes :-)
>
Thanks!
I'm keeping to post comments :-)


Dmitriy Nagirnyak

unread,
Feb 2, 2008, 11:55:01 PM2/2/08
to

Peter Morris

unread,
Feb 3, 2008, 3:22:28 AM2/3/08
to
> I have just got a better idea. Generics.

Was planned. In fact I am about to do it just because it is so quick :-)

public class EcoSmartDispatcherController<EcoSpaceType> :
EcoSmartDispatcherController
where T: DefaultEcoSpace
{
public override Type DefaultEcoSpaceType
{
get { return typeof(EcoSpaceType); }
}

protected T EcoSpace
{
get { return (EcoSpaceType)GetEcoSpace(typeof(EcoSpaceType)); }
}
}

2 mins :-)


> public ProductController : EcoBaseController<MyEcoSpace>
> {
> public void Modify([EcoDataBind]Product product) {}
> }

Minimum required is [EcoDataBind("Product")], there appears to be no way to
get the name of the parameter the reflection attribute is decorating.


>> Allow="FirstName,LastName", //Allows only these items to be set

> But it really annoys me because of Allow/Exclude are strings.

Me too.


> Why do we need it if in .NET 3.5 it is possible to make it checkable at
> compile time...

Show me an example of passing a class property rather than the value of an
object's property and I will put it in. We could use LoopbackIndices but
that would be really long.


Pete


Peter Morris

unread,
Feb 3, 2008, 5:52:44 AM2/3/08
to
>> Allow="FirstName,LastName"

> But it really annoys me because of Allow/Exclude are strings.


I can't see a way of doing this. Can you?


Dmitriy Nagirnyak

unread,
Feb 3, 2008, 6:37:20 AM2/3/08
to
Hello Peter,

> Minimum required is [EcoDataBind("Product")], there appears to be no
> way to get the name of the parameter the reflection attribute is
> decorating.
>

I also cannot find how to do it.
Hmm... Isn't it really impossible in native .NET?...

>> Why do we need it if in .NET 3.5 it is possible to make it checkable
>> at compile time...
>>
> Show me an example of passing a class property rather than the value
> of an object's property and I will put it in. We could use
> LoopbackIndices but that would be really long.
>

C# 3.0 syntax allows to pass property *references* as parameters to methods
using Lambda Expression Trees.

So someting like this should be easy to implement (having knowledge about
Expression Trees).

I'm not sure about the syntax and so on...
Having look at:
http://msdn2.microsoft.com/en-us/library/bb397951.aspx
http://msdn2.microsoft.com/en-us/library/system.linq.expressions.expression.bind.aspx

I assume syntax similar to this is possible:
[EcoDataBind("Product",
Allowed=BinderExt.Allow<Product>()
.Prop(p=>p.Name)
.Prop(p=>p.CreatedDate)
.Prop(p=>p.Price)
.Done()
)]

This of course is hard to say it is easier to use...

What happens there:
1. BinderExt.Allow - creates typed empty list of properties (Expresion Tree
or just custom ones).
2. Each "Prop" adds an item to the list. Param of the "Prop" is a reference
to Product.SomePropertyName.
It returns the same object, so "Prop" can be applied one more time.
3. Done - just returns the list of properties as a string, so it can be used
in MR.

Not sure if it will work. I just don't know all the stuff with Lambdas/Expression
trees etc.

It also should be applied for the .NET Attribute. I'm not sure if it's possible.

ASP.NET MVC uses UpdateObject method. I think this one should be easier to
extend.

We might need to discuss all this on MR/MS MVC forum.
I think there are more than 2 people who don't like *strings* for Allow :-)

But my googling is not effective around that :(

Dmitriy Nagirnyak

unread,
Feb 3, 2008, 6:40:42 AM2/3/08
to
Hello Peter,

>>> Allow="FirstName,LastName"
>>>
>> But it really annoys me because of Allow/Exclude are strings.
>>
> I can't see a way of doing this. Can you?
>

Not really...
I think we'd better ask it on MR forum.


Peter Morris

unread,
Feb 3, 2008, 7:32:43 AM2/3/08
to
> I think we'd better ask it on MR forum.

In a C# NG I was told it is not possible. I was also told the same by
someone very clever :-)


Dmitriy Nagirnyak

unread,
Feb 3, 2008, 8:21:27 AM2/3/08
to
Hi Pete,

>> I think we'd better ask it on MR forum.
>>
> In a C# NG I was told it is not possible. I was also told the same by
> someone very clever :-)
>

Not sure what you mean... I'm probably missing something or not following...
Do you mean C# ECO NG?


Peter Morris

unread,
Feb 3, 2008, 9:51:10 AM2/3/08
to
>> In a C# NG I was told it is not possible.

The Microsoft C# newsgroup.


> I was also told the same by someone very clever :-)

Someone I know who seems to know just about everything about .NET told me it
wasn't possible.

Hope that clears it up :-)

Pete


Dmitriy Nagirnyak

unread,
Feb 3, 2008, 5:14:56 PM2/3/08
to
Hello Peter,

> Someone I know who seems to know just about everything about .NET told
> me it wasn't possible.
>
> Hope that clears it up :-)
>

Yes. Thanks.
We'd better believe him :)

Unfortunately, it seems like all those string Allows are going to stay there
for a long time... :(


Peter Morris

unread,
Feb 4, 2008, 3:34:27 AM2/4/08
to
I could have an additional overload for loopback indices, but I think that
would be far too long.


Dmitriy Nagirnyak

unread,
Feb 4, 2008, 4:39:54 AM2/4/08
to
Hello Peter,

> I could have an additional overload for loopback indices, but I think
> that would be far too long.
>

This is an option, but it would be very specific to ECO.
(That's why it is EcoSupport :-))

I don't think you need to spend much time for that.
Just much more tests needed...

In such cases I would, honestly, better use old, good "manual data binding"
:)

I think if we'd try to "hack" some MR project injecting additional propety
value to form values, we'd, probably, succeed.

So this automatic data-binding should be used carefully.
Especially with ECO. Where having one object instance it is possible (in
many cases) to navigation the whole model.

Anyway... For now the "Allow string" is only one option to prevent it.
I'm just thinking...
If we need to specify explicitly all the properties... Why can't we just
assign manually instead (of course probably using some helpers).

Something like this:

public void Create()
{
Product p = new Product(EcoSpace);
using(b = FormBinder.Start("productPrefix"))
{
p.Name = b.ToString("Name", 255); // With MaxLength
p.Description = b.ToString("Description");
p.Price = b.ToDecimal("Price");
p.NumberInStock = b.ToInt("NumberInStock");
}
}

It still uses strings, but assignment is explicit.

It might be a long discussion...
I think you'll probably pick whatever is available in MR.

0 new messages