Moving SqlDataSource to class file ASP.NET - c#

I have been tasked with moving all SqlDataSource objects out of an ASP.NET pages aspx files and putting them into a separate class file but am lost. Is there a way to create a SqlDataSource object in a separate class and assign query strings to the SelectCommand, DeleteParameters, InsertParameters, etc?
To where you can call the object on a separate page rather than have the code in the aspx?

Yes, you can do that. I would recommend that you move all the database IO to a web service.
I also want to add that this is a very good step that you are taking, as far as the security of your application. Separating your data access from your user IO like this is something I consider to be a must-have security measure. Done right, you will bump up the security of your application significantly.
You can create a WCF web service easily enough. There are plenty of tutorials on the web, and I'll be happy to give you pointers as you go along. The web service would have CRUD (insert, select, update, delete) operations. You can then create an "Object" type datasource on the web page, that points to your web service, and the elements on the page can get their data from those object datasources. You can also instantiate the web service in your code behind, and use it to manipulate the data. When you create the object type data sources, you will specify the service methods that correspond to each of the commands (select, insert, update...). Hope this points you in the right direction, and feel free to ask me more in the comments, or you can initiate a chat and I will give you my email where you can holler at me.

As already mentioned, it is possible to move the SqlDataSource controls out of the WebForm. I'll assume for the moment that your current code declares these controls in the .aspx file. You could change to an imperative approach, for example, and instantiate the datasource controls in an event handler of a WebForm's code-behind class, but you don't gain much by doing so. Indeed, you could even move a lot of the code that does the instantiation into a helper class that is called by the code-behind class, but this doesn't get you much further.
The original intent of the DataSource controls was to provide developers with a way to create rapid prototypes / proofs of concept. But these controls aren't really meant for production systems. They are a violation of the separation of concerns and make unit testing difficult, if not impossible.
In some ways, the DataSource controls can be easier to work with (say, in conjunction with a GridView control). But, this convenience comes at a price, which probably helps explain (in part) why you're being asked to do something with the controls. It's unfortunate that at when ASP.Net 2.0 (WebForms) was released in 2005, the literature that was published at the time heavily promoted the use of these DataSource controls. The community has learned since then that the production value of these controls is questionable, unless you are working on simple systems that don't need to evolve much over time.
As was mentioned by Anon316, you could use a web service to handle the CRUD operations. However, this solution might not be what you really need. Additional overhead is incurred by using a web service (i.e., additional HTTP requests to the service). Having your application make direct calls to the database can still be a very good approach.
With that said, consider creating a separate class (or classes) that provide data access facilities (e.g., a Repository). Entity Framework, for example, makes creating this kind of thing fairly straightforward (and there are many other data access libraries available in the .Net ecosystem). Be prepared for adding more code to the code-behind classes of your WebForms in order to make them interact with your Repository (or other Data Access) class(es). The benefit you'll gain is more testability and reuse of your data access code. Consider putting your data access class(es) into a separate project in your solution (to start).
Whether you create separate data access class(es) in your solution or a web service, you still have significant refactoring to do in order to move away from the DataSource controls. So, again, be mindful of the additional overhead involved in using a web service, recognizing that a web service tends to make sense when you have multiple clients (e.g. web and mobile), not when you only have one.

Related

ObservableCollection in the service layer of the WPF MVVM application

Examples of WPF MVVM apps I've seen on the Internet consider VM a layer which interacts with a service layer which either uses "old" events from an external library, or interacts with web using HTTP or whatever. But what if I build all M, V, VM, service and other parts myself? How to properly build interaction between the service layer and the viewmodel layer? Can I just put ObservableCollection<OrderModel> into the service and return it as is from the viewmodel for the view, or is it considered a bad approach and there're better alternatives?
You can do this - of course you can. The primary reason to do such a thing would be to reduce duplication across multiple WPF applications.
However, a challenge you might have in some scenarios, depending on your service layer/data layer implementation, is long-running services that in turn use database connections. ObservableCollections are enticing from the point of view of having the service layer automatically synchronising changes made by an application to a data store; however it gets complicated when you want to communicate changes that originate from the data itself (i.e. in response to some other process that creates/modifies data).
The service layer can't really replace the instance (i.e. in the case of large-scale changes), since it is no longer the sole owner of the reference - but even if it could, replacing the instance would pretty much break any binding the UI has to the collection.
So you stick to trying to keep the one instance up to date. If your services are bound to a database, then unless you code-up some form of long-running monitoring process within your service, the only simple way to keep an ObservableCollection up to date after it's been dished out would be to hold database connections/contexts (in the case of Linq to Sql or EF) open - because otherwise related objects etc are not going to be able to retrievable (unless you force all objects to be read in one go - which is not scalable).
Okay, so it's possible to write some form of management layer which can manage the connections for you - but in addition to the inevitable polling, or perhaps SQL Server notifications that you might use, I believe the code might get quite complicated.
That said, it really does depend - that particular issue is one to look out for, but it might be that you have an architecture and environment in which such things simply don't matter.
My advice, if you want to try it - go ahead. For me? I've thought about it - and beyond adding INotifyPropertyChanged to some domain models, I stick to the idea that an application has it's own VM. Multiple applications might share the same VM - but that won't be internal to the service layer itself.
A service layer provides access to data and business logic in a typically one-shot way. Classes in the VM pattern are intended to have a much longer lifespan - and trying to code a long-running service layer is notoriously very hard to do - especially if you want it to try and solve all the problems that all future applications might present. Inevitably you will end up coding services or VM types within the service layer for a single application only - in which case it might as well have gone in that App's codebase.
I'd be tempted to use an ObservableCollection only from the point at which the "observable" aspect is relevant, which is generally the VM exposing something to the V. Further down the stack (i.e. the M) I'd be tempted to stick with more generic things like lists and collections (unless you specifically need for things to be otherwise). Its easy enough for the VM to create an ObservableCollection based on any old IEnumerable in any case.
A reasonable question though, especially as ObservableCollection's placement in the System.Collections namespace would seem to suggest that Microsoft don't particularly think of this as a specialized class (and certainly not wpf-specific).
I wouldn't do that for a number of reasons. They're documented here: Common mistakes with an observable collection
The author goes through several mistakes people make with them, including using them in the service layer.

LINQ to SQL in Silverlight client

Okay, so I have this Silverlight client program. I'm not allowed to use the web project, but I do need to be able to read from an SQL database for my data.
Some internet searching brought me to LINQ to SQL and the System.Data.Linq.DataContext object, as well as SQLMetal.exe. I have created my data context object from the meta data in a remote SQL database and the code looks okay (from what I can tell - all the right names and types seem to be there).
What I wanted to do was add this into Silverlight, but I realised, on importing the code, that you can't use System.Data in a Silverlight application, which sort of rules out having this code in the Silverlight client itself. Now this is annoying because a DataContext quite conveniently comes with properties which are tables and such like (I find those really convenient in Silverlight).
So I can't do it the 'normal way'. I can do it with a WCF service, but... well, here's where I could use some advice. I can create a WCF service with asynch calls, but I'm not really sure in what way to wire up the DataContext object. I mean... I need access to the classes in there within my Silverlight application (for my entities in the database) (and I'm not quite sure how to do that - help there would be appreciated). Then to synchronise it all up? Well, I could use some suggestions. For example, before, I have an exposed ObservableCollection. In its getter, it repopulated itself with the contents of, for example, Context.Customers. This made things nice and easy, but I can't see a way of doing something like that now. If I made a call to an asynch service for every 'get', surely this would be unacceptably slow.
If you could help me pick my way through this, I would be grateful. Thanks.
You definitely need to read about Entity Framewrok and couple articles about using WCF RIA + EF in Silverlight applications.
Hope, that will help you.
As mentioned above, you can use RIA services.
But more importantly... you should never use the classes that are generated in LINQ to SQL or EF in your client application. Your client application should only know about and use Domain Layer objects. Your datacontext and the types it uses should stay buried behind a repository pattern that gives you back Domain types.
Your client, whatever that may be (Silverlight app, WPF app, etc) only needs to (and should only) use these domain types. This is part of the whole separation of concerns and SOLID principles. Because I can guarantee you at some point in the lifecycle of the app you will swap out your source for data, so you may end up using Entity Framework, or NHibernate to talk to the db instead, in that case your client would be hard-wired to your LINQtoSQL types, and you wouldn't be able to swap out the ORM layer without breaking the client.

database access from multiple applications

I have a windows form application(c#) and an asp.NET web application which both access Sql Server database. I want to centralize the database access. Which metedologies should i follow? What is the common approach to this issue?
Writing DAL and Model Libraries and using them in both application?
Writing WCF service including DAL model and using this service with both applicaiton?
None of the above?
Can you give me any idea?
Thank you.
I would go with the WCF approach. Keep in mind that when (not if, when) you have to make changes that pertain to one app, but not the other (yet), you will have to account for that in the common layer, so using interfaces may make your life a little easier.
The cleanest way is to wrap the DB with a WCF services.
If you don't write large amounts of data in one go you can use a WCF Data Service; this directly wraps an Entity Framework model and you can configure access to tables and methods in various ways.
What you want is to have one place where the DB is accessed, so that if there is an issue, you can fix it in one location, for instance.
Furthermore, if you want to log all calls to a particular table, for instance, the only way to make sure that will be done is by centralizing all calls to the DB this way and not allow anybody direct access to the DB.
Wrap the service, then keep the connection string secret.
I think using the SOA approach is really better (WCF or WebServices with a DAL layer) because this way you don't need to publish your DAL dll with the Windows Forms exe. Then, all changes to your data model will automatically happens to your both UI clients.
Remember that this can cause its own problems:
Concern with security so that your Services cannot be accessed directly by URL, allowing someone to run your methods.
Concern about maintenance, because changes in data layer that needs to affect only one interface will be more difficult to control and needs to be better planned before (with the creation of new methods specific to certain intercace).
Decrease in performance, because the HTTP access is always more costly than direct communication with a dll.
Risk of lack of communication with the server, something that is expected to ASP.NET but requires additional concerns in the Windows Forms client to behave properly in these cases.
Option 1 seems simpler and I would do the same.
Option 2 with WCF will add additional code to your product and hence maintenance. Also this would mean an additional layer as well.
Corporate programmers like the second option (WCF service including DAL).

What special considerations should I make when creating an object model that will be consumed by a desktop application and web site?

I'm writing a tool in C#.Net that will be used to generate Catalogs of content which users can browse. Initially I am creating a WinForms based interface, but in the future I'd like to be able to create a web based interface as well. So I've been careful to generalize the interface to a Catalog so that it does not depend on a specific UI.
My only experience with web development has been creating my own HTML website back in the early 90's, and I've done a little ASP (not ASP.NET). Now with ASP.NET it seems that I should be able to leverage my existing C#.Net object model, to create a web base interface. But I really hasn't done anything with ASP.NET beyond a simple hello world example.
Are there any special considerations I should make in designing my object model so that later I can create a web interface to it?
Here are few things to follow:
You should package your object model
is separate project (that you need
to do anyway to share it among
different projects) and make sure
that you do not add specific
references to it (for example, don't
add System.Web, WinForms, WPF etc) -
this will automatically avoid any
unwanted dependencies.
Try to have your classes as lean as possible. Avoid classes that track change states etc - in web scenario, tracking state over multiple requests is expensive. So it's best to have to your objects carry data only.
Consider the possibility that your objects may need to be serialized and/or passed over a wire. For example, a middle ware services serving both windows & web client. Or web page storing the object in the view-state.
There really shouldn't be that big a difference.
Be careful about placing too much “intelligence” in your entity classes. That’s a pattern I’ve seen often in Windows apps. Don't make references to controls that are specific to Windows Forms development in the parts of your project that you want to reuse for the web application.
Repository patterns work well with both Windows and Web applications, because you often want to optimize the web apps differently for performance with multiple users.
Your requirement can be handled with a multi-tier architecture:
http://en.wikipedia.org/wiki/Multitier_architecture

How do I make a client-side helper class in Silverlight?

In Silverlight, I call my Silverlight-enabled WCF service asynchronously to retrieve, say, a list of values for a combobox. On the server, I cache these values for performance. But I want to cache them on the client to prevent the unnecessary round-trip.
Now, I understand how to use local storage to cache them except that I do not want all of the "if in local storage, return local storage values else get values from server asynchronously" stuff in the code-behind of my xaml app.
So, I tried moving that code to a helper class but the async calls need a callback which is where I get lost. I tried passing a generic EventHandler into my helper class but the helper class method really needs to be static. So, that is throwing me off. Will my helper method need to be non-static, and, if so, do I need to worry about thread safety? Aaarh! Too many questions! Haha. Anyway, I bet some smart person out there can tell me a better way to approach this almost immediately! Thanks in advance.
I've done one major Silverlight app in the past. It has taught me that you shouldn't fight against the system.
If I'm not mistaken, Silverlight itself uses the browser network layer to connect to the internet. So you can still leverage--and Silverlight still respects--things with proper cache-control headers and such.
So just from my experience, I'd suggest that you try to make the server component (WCF server) do proper output-caching ala ASP.NET style and the network layer in Silverlight and the hosting browser will handle caching automatically for you.
You may have better luck with RESTful WCF mode since you can leverage proper HTTP caching throughout, see this blog post: REST in WCF – Part X – Supporting Caching and Conditional GET for a start.
This also makes your code less complex, since you don't have to add yet another complex layer to your system and tame it to work with the confusing XAML binding system.

Categories