Having Problems with ObjectFactory

Having Problems with ObjectFactory

Old forum URL: forums.lhotka.net/forums/t/10362.aspx


Jav posted on Wednesday, May 11, 2011

So far I have worked exclusively with In-Object ADO dataaccess with tremendous success.
I am now confronted with a situation where nothing but an ObjectFactory would do for data access.  I only need to Fetch - no updates or inserts are needed.  Pretty simple, I'd say.

 I have followed the InventoryDemo exactly, but my Fetch method in the DAL project is never called.  I am now using a tiny "test" Solution with EFrameServer and EFrameClient libraries with a single class: EFrame and a Data access library called DAL with one class called PersomName.  Here's the code in all.

EFrame:
namespace FrameLibrary
{
    [Serializable]
    [Csla.Server.ObjectFactory("DAL.PersonName, DAL")]
    public partial class EFrame : ReadOnlyBase<EFrame>
    {
        public static PropertyInfo<string> DefaultNameProperty = RegisterProperty<string>(c => c.DefaultName);
        public string DefaultName
        {
            get { return GetProperty(DefaultNameProperty); }
         }
    }  
}

EFrame.Client:
namespace FrameLibrary
{
    public partial class EFrame : Csla.ReadOnlyBase<EFrame>
    {
        public static void GetEFrame(EventHandler<DataPortalResult<EFrame>> callback)
        {
            DataPortal.BeginFetch<EFrame>(callback);
        }
    }
}

EFrame.Server:
namespace FrameLibrary
{
    public partial class EFrame : Csla.ReadOnlyBase<EFrame>
    {
    }
}

DAL:
namespace DAL
{
    public class PersonName : ObjectFactory
    {
        public EFrame Fetch()
        {
            var frm = new EFrame();
            LoadProperty(frm, EFrame.DefaultNameProperty, "Name Is Object Factory");
            return frm;
        }
    }
}

The error I am getting is:
An Error Has Occured
DataPortal.Fetch failed (Factory type or assembly could not be loaded (DAL.PersonName, DAL))

What am I missing?  Thanks.

Jav

JonnyBee replied on Wednesday, May 11, 2011

.NET is quirky in how you specify a fully qualified class name.

There can be no whitespaces after comma before assemblyname:

  Must be:  [Csla.Server.ObjectFactory("DAL.PersonName,DAL")]

If ObjectFactory still fails try to add a criteria parameter to Fetch method (I believe this should not  be required) and change return type to object

        public object Fetch(object criteria)
       {
            var frm = new EFrame();
            LoadProperty(frm, EFrame.DefaultNameProperty, "Name Is Object Factory");
            return frm;
        }

 

 

Jav replied on Wednesday, May 11, 2011

Thanks Johny,

Removing the space and adding the criteria parameter did not help - I still get the same exact error. 

I have been pouring over Rocky's Csla4 Series of DataAccess book.  On Page 8 he says:

"As with the encapsulated models, if you implement an object factory that will run on Silverlight or WP7 the methods must accept a callback parameter that is invoked when the method is complete. "

He also gives an example:
public void Fetch(int id, Csla.DataPortalClient.LocalProxy<PersonEdit>.CompletedHandler handler)
{

}
 But from Csla 4.2 sample I do not see that being done. So I am confused.

Javed

Jav replied on Wednesday, May 11, 2011

I thought I will try what the book says.  But the following line was not acceptable:

public EFrame Fetch(Csla.DataPortalClient.LocalProxy<EFrame>.CompletedHandler handler)
{
}

The error says:
The non-generic type 'Csla.DataPortalClient.LocalProxy' cannot be used with type atguments

 

RockfordLhotka replied on Wednesday, May 11, 2011

You should only worry about the CompletedHandler parameter if your factory code is running on the Silverlight client. If your factory code is running on a .NET application server (even if called by a SL client) then there's no such parameter.

If the data portal can't create the factory object or call the method, it will throw an exception. Do you have proper exception handling set up so you are notified about the failure? That would help debugging quite a lot.

Jav replied on Wednesday, May 11, 2011

Here is the more complete error. 

An Error Has Occured

Csla.DataPortalException: DataPortal.Fetch failed (Factory type or assembly could not be loaded (DAL.PersonName,DAL))

   at Csla.Server.ObjectFactoryLoader.GetFactory(String factoryName) in E:\MyDocuments\Visual Studio 2010\Projects\Csla4.0\Source\Csla\Server\ObjectFactoryLoader.cs:line 55

   at Csla.Server.FactoryDataPortal.InvokeMethod(String factoryTypeName, String methodName, DataPortalContext context) in E:\MyDocuments\Visual Studio 2010\Projects\Csla4.0\Source\Csla\Server\FactoryDataPortal.cs:line 58

   at Csla.Server.FactoryDataPortal.Fetch(Type objectType, Object criteria, DataPortalContext context) in E:\MyDocuments\Visual Studio 2010\Projects\Csla4.0\Source\Csla\Server\FactoryDataPortal.cs:line 138

   at Csla.DataPortal.Fetch(Type objectType, Object criteria) in E:\MyDocuments\Visual Studio 2010\Projects\Csla4.0\Source\Csla\DataPortal.cs:line 245

   at Csla.DataPortal.Fetch(Type objectType) in E:\MyDocuments\Visual Studio 2010\Projects\Csla4.0\Source\Csla\DataPortal.cs:line 186

   at Csla.Server.Hosts.Silverlight.SilverlightRequestProcessor.Fetch(SilverlightCriteriaRequest request) in E:\MyDocuments\Visual Studio 2010\Projects\Csla4.0\Source\Csla\Server\Hosts\Silverlight\SilverlightRequestProcessor.cs:line 144

System.InvalidOperationException: Factory type or assembly could not be loaded (DAL.PersonName,DAL)

   at Csla.Server.ObjectFactoryLoader.GetFactory(String factoryName) in E:\MyDocuments\Visual Studio 2010\Projects\Csla4.0\Source\Csla\Server\ObjectFactoryLoader.cs:line 55

   at Csla.Server.FactoryDataPortal.InvokeMethod(String factoryTypeName, String methodName, DataPortalContext context) in E:\MyDocuments\Visual Studio 2010\Projects\Csla4.0\Source\Csla\Server\FactoryDataPortal.cs:line 58

   at Csla.Server.FactoryDataPortal.Fetch(Type objectType, Object criteria, DataPortalContext context) in E:\MyDocuments\Visual Studio 2010\Projects\Csla4.0\Source\Csla\Server\FactoryDataPortal.cs:line 138

Javed

RockfordLhotka replied on Wednesday, May 11, 2011

It sounds like the assembly containing your factory class isn't in the web server's bin folder.

Jav replied on Wednesday, May 11, 2011

It looks like the issue may be related to the old crossdomain / clientaccesspolicy issue. 

The code I posted above was from a tiny test project.  Originally I had not referenced the DAL project in my Web project.  But now I can see the DAL dll in the bin folder and still I see the error.

When working with my original project, as I was walking through the csla code just now, I came across an error that talks about this being a crossdomain access issue.  I saw this error many a month ago (still remember the headaches it caused then) and have always had both those files in my web project.  I have now copied both files in the test web project also, and I am getting the same exact error.

In the test project I am using the CslaDataProvider.  But in my main Solution the call for the data originates from a ViewModel's constructor.

Javed

Jav replied on Wednesday, May 11, 2011

Here is the complete text of the error.  The crossdomain thing must be a red herring since I am working on my local machine, and not even in iis but in the development server.  What I am trying to get from the ObjectFactory is a ReadOnlyList.  I see this error in:

dp.FetchCompleted += (o, e) =>
   {
   }

Here e.Object is null and bring the mouse over e displays the following as the DataPortalResult err:

{: An error occurred while trying to make a request to URI 'http://localhost:7371/WcfPortal.svc'. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. This error may also be caused by using internal types in the web service proxy without using the InternalsVisibleToAttribute attribute. Please see the inner exception for more details.
   at System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult result)
   at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
   at System.ServiceModel.ClientBase`1.ChannelBase`1.EndInvoke(String methodName, Object[] args, IAsyncResult result)
   at Csla.WcfPortal.WcfPortalClient.WcfPortalClientChannel.EndFetch(IAsyncResult result)
   at Csla.WcfPortal.WcfPortalClient.Csla.WcfPortal.IWcfPortal.EndFetch(IAsyncResult result)
   at Csla.WcfPortal.WcfPortalClient.OnEndFetch(IAsyncResult result)
   at System.ServiceModel.ClientBase`1.OnAsyncCallCompleted(IAsyncResult result)
:
   at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
   at System.Net.Browser.BrowserHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
   at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result)
: Security error.
   at System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
   at System.Net.Browser.BrowserHttpWebRequest.<>c__DisplayClass5.<EndGetResponse>b__4(Object sendState)
   at System.Net.Browser.AsyncHelper.<>c__DisplayClass4.<BeginOnUI>b__1(Object sendState)
}

The innerexception is null.

Javed

 

Jav replied on Wednesday, May 11, 2011

My little demo project is now working.  Looks like it was just a matter of getting ALL my ducks in a row - not a trivial thing sometimes.  Now on to my "real thing" project.

Jav

JonnyBee replied on Wednesday, May 11, 2011

What is the UI and runtime framework for your client?

Also  make sure that DAL.dll is present in the bin folder on the server side code (WCF Service) ?.

 

Jav replied on Wednesday, May 11, 2011

Rocky,

I will set up exception handling to see where the error is.  When I tried to step through the Csla code, however, I did not come accross any exception.  In fact it is as if there was no attempt to go to the factory class.  I have a breakpoint in the factory method and it is never hit.  The silverlight page displays with no data (whiich is expected) and there is a little box with the error that I reported on my first post.

Johny,

I am using VS 2010 (Not SP 1), Framework 4, SL 4,  VS Delopment Sever.  The Solution I am using is absolutely the minimal SL App you can ever create.  It works fine when the DataPortal_Fetch is not .Server code.

Javed

Copyright (c) Marimer LLC