CSLA and the new ASP.NET Web API

CSLA and the new ASP.NET Web API

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


TSF posted on Tuesday, February 28, 2012

I was going through some of the examples on the new web API that is part of the asp.net mvc 4 beta release.  Does CSLA fit with the Web API model?  I'm new to ASP.NET MVC and am trying to figure out if I should consider the web API for use with CSLA.  Thanks.

RockfordLhotka replied on Friday, March 02, 2012

How do you want to use it?

I can see two ways it may be useful.

First, you can expose a web api that is backed by CSLA business objects. I haven't looked into this, but it makes sense to do this because a web api is just a service endpoint, and many people already implement their services (asmx or WCF) using CSLA objects. I expect the web api services will be very similar.

Second, the data portal might use the web api as a transport at some point. If the web api becomes the preferred model for communication or service hosting (over WCF) then it makes sense that the data portal would support a web api channel. That shouldn't really affect the way the data portal works - it would be another option in addition to WCF, asmx, Remoting, and Enterprise Services. (though to be fair, I essentially deprecated everything but WCF starting with CSLA 4).

artsd replied on Sunday, March 04, 2012

I am also interesting in building an ASP.NET Web API with CSLA. I am reading the CSLA 4 books (especially MVC) to try to understand this. I am hoping that there is a way to make the api without creating data transfer objects for every CSLA object I want to expose to the api. It looks like CSLA MVC has the CslaModelBinder that lets you directly use the CSLA objects themselves. I don't yet understand how the MVC controller knows that the posted data matches a particular object (when using the strong model binding technique). But that is a generic MVC question I have, not CSLA specific.

I also don't understand all the trouble the CSLA MVC Controller goes through to update an existing object by creating a new object. From the book:

An edit operation requires creating an instance of the business object, loading its properties with the postback data, and saving the object to update the data. This is a little challenging, because the default value of the IsNew property is true and so there needs to be a way to force a “new” object to be updated, not inserted.

Why not just load the object, update changed properties, and save? Doing the above technique prevents the use of optimistic concurrency using a "last modified" timestamp. It also seems to trust that the client is providing trusted input.

Any chance we will see a Csla.Web.Http.ApiController to match the Csla.Web.Mvc.Controller?

 

 

RockfordLhotka replied on Sunday, March 04, 2012

Arthur Dumas

Any chance we will see a Csla.Web.Http.ApiController to match the Csla.Web.Mvc.Controller?

I suspect that'll happen.

The thing to remember is that we only have so much time to work on this stuff, and there's a lot of things going on. ASP.NET MVC 4, Web API, .NET 4.5 (with big changes to Web Forms and the whole new async/await stuff), WinRT. And pretty soon another version of Windows Phone.

Perhaps even more important, I am happy to accept help :)  

At some point I'll get time to research Web API. I can't say exactly when. In the meantime, I welcome any specific insight into the sorts of helpers necessary to make it work smoothly with CSLA objects. Or even more importantly, things that need to happen to core CSLA to support platform features.

artsd replied on Sunday, March 04, 2012

I totally understand where you are coming from. When I look at the additions to CSLA just within the last year to support WinPhone, Mono, WinRT, it is an amazing amount of work -- whole new platforms that CSLA is supporting that didn't even exist 18 months ago.

If my research into Web API using CSLA produces anything I will be sure to get in touch. Right now I was trying to return an IEnumerable of a read-only root list just to see how this looked when serialized to xml and json. I haven't tried json yet but the xml didn't work. Got the following error:

You must write an attribute 'type'='object' after writing the attribute with local name '__type'

Found a thread here http://forums.asp.net/t/1773173.aspx/1?You+must+write+an+attribute+type+object+after+writing+the+attribute+with+local+name+__type+ that describes another person having this problem but one of the proposed solutions was unworkable (decorating base class with [System.Runtime.Serialization.KnownType(typeof(DerivedClassGoesHere))] to describe every possible derived class!!! -- impossible to do when I have hundreds of CSLA classes and my base classes are in different assemblies from the real bus obj library). Hopefully the Web API team figures this out soon (they say they are working on it).

Edit -- did a little more digging in case anyone else is reading this. It looks like Web API uses normal XmlSerializer so I tried to use it to serialize my root read only list. It failed with some old junky base class property I had around that was IEnumerable<object> which I wasn't using. But then the next problem was with MobileDictionary. I suppose the whole reason the MobileDictionary exists is to solve serialization problems so I shouldn't be surprised.

Why doesn't MobileDictionary implement IXmlSerializable?

I think I will take a try at using Peter Welter's serializable generic dictionary http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx

RockfordLhotka replied on Monday, March 05, 2012

Arthur Dumas

It looks like Web API uses normal XmlSerializer so I tried to use it to serialize my root read only list. It failed with some old junky base class property I had around that was IEnumerable<object> which I wasn't using. But then the next problem was with MobileDictionary. I suppose the whole reason the MobileDictionary exists is to solve serialization problems so I shouldn't be surprised.

Why doesn't MobileDictionary implement IXmlSerializable?

That'll be a problem then. At no point has CSLA ever supported XmlSerializer. In fact, several of the basic assumptions made by XmlSerializer are in direct conflict with basic assumptions made by CSLA.

XmlSerializer is designed specifically to serialize/deserialize data transfer objects. It assumes all objects have the following characteristics:

CSLA objects should be (or at least CSLA assumes they will be) designed with the following characteristics:

BUT even that 180 degree mismatch isn't the REAL ISSUE.

The real issue is that you don't want to expose your internal object model as your external service contract.

Your external service contract can't change. Once you've exposed it, you will have unknown numbers of consumers working against your service contract, and if you change that contract then you break those consumers.

If your business object model IS your contract, then you can never change your business object model. I ask you: how will you maintain your application if you can't change your object model????

In other words, I have never felt any motivation to directly expose business objects via service interfaces, because that way lies madness. Or beyond that sea there be monsters. Whatever metaphor you'd like to use for certain doom, feel free to insert it here :)

artsd replied on Monday, March 05, 2012

I understand what you are saying about:

The real issue is that you don't want to expose your internal object model as your external service contract.

I guess I saw that MVC users had an easy job and didn't have to create custom DTO -- could just use CSLA directly and use binding helper.

Was trying to be lazy efficient and not do the DTO. But you are of course correct that using CSLA as the DTO certainly ties your hands and is not the way to go.

So now I am working on a DTO base class that can return broken rule details in addition to normal properties. Will then make a helper to do to/from mapping. But also get the advantage of being able to more easily expose composite contract that is not just one-to-one with bus obj.

Thanks!

RockfordLhotka replied on Monday, March 05, 2012

MVC users don't really have such an easy job though. They have to create a contract too, it is just in the form of a view. And it is a contract with a human, not another machine, but it is still a contract of sorts, and it still rearranges and/or hides the data.

What would be really cool (imo) would be something like an MVC view engine that worked with service contracts.

In fact, I wonder if you couldn't use Razor to accomplish that goal? Or if someone on the Web API side of things has thought of this sort of thing?

Why wouldn't the result of a service call be a type of view? A JSON or XML view to be sure, but still it would be a view.

tiago replied on Tuesday, March 13, 2012

RockfordLhotka

[quote user="Arthur Dumas"]

It looks like Web API uses normal XmlSerializer (...)

That'll be a problem then. At no point has CSLA ever supported XmlSerializer.

(...)

Good news!

"We on the web team will be including JSON.NET as the default JSON Serializer in Web API when it releases, so that'll be nice."

Scott Hanselman in http://www.hanselman.com/blog/OnTheNightmareThatIsJSONDatesPlusJSONNETAndASPNETWebAPI.aspx

RockfordLhotka replied on Tuesday, March 13, 2012

Probably not as good as it sounds. The JSON serializers have the same limitations as XmlSerializer...

In any case, the core architectural issue remains the same: you don't want to directly expose your internal implementation as an immutable external contract.

rfcdejong replied on Friday, April 05, 2013

This post is a year and two months old, but i believe the web api is becomming more and more the preferred model for communication (over WCF). REST services over SSL are secure enough and alot easier to implement. With 4.5 default being claim based and all those Identity providers lately... Just a bearer token in the header. Hense look at the WAAD (Windows Azure Active Directory) Graph API, microsoft is also just creating new services based on REST. Why would you still use WCF? Only when not using SSL HTTP WCF services or using stuff like MTOM. (or when the serializer aren't strong enough)

I did not believe in REST vs WCF a couple of years ago, but now i'm turned.

imh CSLA should at least offer a ApiDataPortal for REST (if it will be possible)

PS: I believed in Silverlight a couple of years ago so i might be wrong again ;)

RockfordLhotka replied on Saturday, April 06, 2013

I agree that Web API is becoming the preferred communication mechanism for non-enterprise scenarios, and for some enterprise scenarios.

The thing to keep in mind is that the data portal is an n-tier technology, so being "open" is not a design consideration.

It would be extremely easy to create a Web API data portal channel, and I may do this at some point. But it won't be RESTful or open. It will provide the exact same data portal behaviors you have today, by passing a binary byte array via a REST service.

For that matter, the data portal is an open architecture. You can easily implement your own transport channels (proxy/host pairs) to use any synchronous network technology of your choice. In other words you don't need to wait for me if you have a pressing need :)

I would recommend looking at the old asmx channel to see how I did that, because the Web API channel will work in essentially the same way - run the serializer to create a byte array, and pass or accept the byte array via the GET/PUT operations, then run the serializer on the receiving end to deserialize the byte array back into the object graph.

This hasn't been a high priority for me, because the REST people will hate what I'll do (with a passion), and it offers no value to anyone already successfully using WCF.

andy replied on Thursday, April 24, 2014

Very good discussion.  Now I want to learn more about your new raw http channel.

Any resources?

RockfordLhotka replied on Thursday, April 24, 2014

Not yet, I did most of the implementation just yesterday and am still trying to optimize it before putting the code into CSLA itself.

My plan is to have it be a full data portal channel though, so it will be supported on (hopefully) all platforms, not just WinRT/WP8.1.

Peran replied on Thursday, April 24, 2014

Hi Rocky,

A timely post!

I'm currently starting a prototype using AngularJS in the browser and CSLA/WebApi on the server (JSON interface I assume).

I would be interested in trying your new code, so I can see your thoughts on how CSLA/WebApi play together, and whether I'm heading in the right direction!

 

Regards

 

Peran

 

kirkpabk replied on Monday, June 02, 2014

Hey Rocky, be a fan for a while now--geez... has it been a decade already??  

Anyway--my two cents... wrestling one convention or practice in favor of another... relaxing constraints... I don't think that's what your community is necessarily trying to convey.  Perhaps a comprise in that they are seeking a standardized interface with CSLA and WebAPI (perhaps OWIN/Katana based) which utilizes the CSLA (internal) mechanisms which improve the XMLSerializer issue, but interface such that when the XML or JSON serializers fail, simply issue up the best practice Http Status responses.  Perhaps some extensions or helpers which help the controller authors interact with the back end a bit easier.  

Long story short, I believe this can be growth and leveraging the best of both worlds while remaining true to the elements that make both widely accepted.  Here's another thought, is it CSLAs responsibility to police (perhaps too strong--and not intended that way) the full pipeline of contracts?  I tend to believe that there are conventions (both existing and emerging) which can be tailored to meet the goals of your product and the goals of so-called modern architecture without compromising each other.

Does this make sense?  Keep up the good work!

v/r

BK

TSF replied on Friday, June 06, 2014

Something Rocky said in a more recent reply made me realize that I wasn't thinking correctly about my situation when I originally asked about the Web API.

"The thing to keep in mind is that the data portal is an n-tier technology, so being 'open' is not a design consideration."

This statement is extremely helpful. For my part, whether CSLA continues to use WCF or switches at some point to the WebAPI for its primary mechanism, it doesn't really matter in so far as it is taking care of the implementation for me. One less thing that I have to do...and since it is part of an n-tier application, I'm not particularly concerned with whether it meets the open RESTful standards.

RockfordLhotka replied on Friday, June 06, 2014

The current beta of 4.5 includes a new HttpPortal for the data portal that does use Web API if your data portal server is MVC 5. If your data portal server is MVC 4 the host is just a controller. The client doesn't care which server technology you are using.

This is not strictly RESTful of course, because this is a data portal channel that uses the exact same semantics as the WCF channel (and the Local/asmx/Remoting/EnterpriseServices channels).

You can switch from the WcfProxy to the HttpProxy and the client won't care - which is the whole point of the data portal.

I implemented this new HttpProxy/Portal channel because the new Windows Phone 8.1 WinRT environment doesn't support WCF, so I needed a new data portal channel for that platform.

It turns out though, that by using the new HttpClient API from Microsoft we now finally have a consistent client-side API for calling services, because HttpClient (via NuGet) is available for all platforms.

TSF replied on Friday, June 13, 2014

"the new Windows Phone 8.1 WinRT environment doesn't support WCF"

Are you referring to WinRT universal apps? Also, is there a sample app showing the HttpProxy in use?

RockfordLhotka replied on Friday, June 13, 2014

Universal apps yes, but the limitation is because WinRT on WP8.1 doesn't have WCF and universal apps use portable class libraries and those are limited by the lowest common denominator.

If you don't care about Windows Phone then this is a non-issue, but given my ongoing goal of making CSLA support all platforms it was something I had to take on as an issue.

The sample I've been using to test this (and some other stuff) is

https://github.com/MarimerLLC/csla/tree/master/Samples/WinRT/SimpleApp

At the moment the code is configured to use BrokeredProxy, which is a way for a WinRT app to use the data portal running in full .NET on the client device such that it can be called from a WinRT client.

But if you look at the two web projects you can see how the data portal controller is set up in MVC 4 and MVC 5 (page and web api respectively), and in the WinRT app.xaml.cs you can see the commented lines that configure HttpProxy on the client.

As you'd expect, the rest is transparent - your only concern (as always) is configuring the client and setting up the server.

Copyright (c) Marimer LLC