Showing posts with label asp. Show all posts
Showing posts with label asp. Show all posts

Monday, October 29, 2012

[.NET] Updating Detached Objects in Entity Framework

Here's the scenario.

An object is being passed like this


  1. Object gets pull from the database through the Business Logic layer and WCF, as well as getting converted into a detached object.
  2. Values are changed in the Business Logic Layer.
  3. Object gets passed back into the WCF for an update.
I've seen several ways of how a detached object could be updated. Previously in the data access layer, I was retrieving the original object from the database and getting the object again by the original's entity key. Then updated the values and applied the changes. It looks something like this:

using (MyDBContext db = new MyDBContext ())
                {

                    My_Object obj =  db.GetObjectByKey(GetObjectFromDatabaseByID(id).EntityKey) as My_Object;

                    obj.Name = <newName>;

                    if (obj != null)
                    {
                        db.ApplyCurrentValues("My_Object_Table_Name", obj);
                        db.SaveChanges();
                        return "Succesfully Updated!";
                    }
                    else
                        return "Record Does Not Exist.";
                }

So one thing, the method that surrounds this code is only passing an 'id'. There is no objects coming in. Therefore, the object would have to be retrieved again to use its Entity Key to grab the object again, except with an attached state. Another parameter that was passed into the method was the newName. So this newName variable has to be assigned to the new attached object. Only then, we can apply and save the changes. Yes, this is a crude way of doing it, but it works.

Recently, I found a new way of handling an update. So what if we pass in a whole object? Will we have to consider the change of all members of the object? What if the object has 50 members? Well, coding will definitely suck. This method was posted on MSDN, so I'm just going to take it as a valid strategy, and it goes something like this:

 EntityKey key = default(EntityKey);
                object originalObj = null;

                using (MESDataModel.e_MESEntities db = new MESDataModel.e_MESEntities())
                {
                    key = db.CreateEntityKey("KIT_Part", ct);

                    if (db.TryGetObjectByKey(key, out originalObj))
                    {
                        db.ApplyCurrentValues(key.EntitySetName, ct);
                        db.SaveChanges();
                        return "Succesfully Updated!";
                    }
                    else
                    {

                        return "Record Does Not Exist.";
                    }

                }

In this situation, we are creating an entity key out of the passed in object. If it already has a key, then it will return the original instead of creating a new one. Similar to the first method, we are using the key to retrieve an attached object. At this point, the attached object and the passed in object now has the same keys. Call ApplyCurrentValues and the data from the passed in object will write to the attached object within context. This is pretty much MSDN's definition of what ApplyCurrentValues does. Save changes and everything should work. Hope this kind of helps.

Hmm, Okay, what about using DetectChanges?
This method seems to be good, if you are pulling straight from the database, writing new values, and saving it back to the database. No detached objects involved here. If there is a way to use this method with cross platform in mind (Android, iPhone), please let me know.

Friday, October 5, 2012

[.NET] Setting up WCF in Virtual Directories of IIS

Alright, this one was an adventure for me. So this info will be here for the next time I need to set up WCF in a virtual directory. This tutorial will start from the beginning, which is installing IIS. This is assumed that Visual Studio 2010 is already installed. So let's get started with the list:

1. Install IIS through Programs and Features. If you're feeling lazy, just try to install as much of the IIS options you can check. Otherwise, you just need ASP.NET under World Wide Web Services. This will auto-check dependencies as well. And IIS Metabase under IIS 6 Management Compatibilty. Also, you will need to go under the Microsoft .NET Framework 3.5.1 section, which is separated from the IIS section btw, and check both boxes under that. They should have the description with Windows Communication Foundation within it.

2. Make a new wcf service project or open an existing one. Go to it's project properties. Under the Web tab, select he use local IIS option. When you save, it will create the virtual directory for you. There are other ways to deal with the virtual directory like publishing, or adding it directory in the IIS manager. It is up to you.

If you get an error when you try to save the project properties, check if you have all the IIS components installed. VS2010 does a good job telling you what you need anyways.

Hmmm, that seemed to be a short list. But here are some problems + fixes that you may have to encounter.

Errors you may have encountered:

1. "Something about having a duplicate handler in your web.config". What happened here was that I tried to add a handler myself before installing the WCF stuff under Microsoft .NET Framework 3.5.1 section. Therefore, IIS couldn't even populate it's integrated handlers, let alone, let me add any more handlers. So I had to edit the web.config manually by copying it outside it's original directory, removing the handler, and then moving it back into the original directory. It will not let you edit it if you open it within the original directory.

2. 404.17: The requested content appears to be script and will not be served by the static file handler.

Check if you installed all the necessary components for IIS and WCF. You may have to run aspnet_regiis.exe -i under the command line if you have ASP.NET 4.0. After doing this, WCF should run smooth and you should be able to see the .svc file in your browser as intended.  This solution may be different if you are running an older version of ASP.NET.

3. Make sure  the application pools between the website and your virtual directory are ASP.NET 4.0. I haven't thoroughly tested this one out yet. I changed the website to ASP.NET anyways just to be safe. 

Local Host Stuff 

 If you tried to access your IIS or .svc from another computer, you may find that it will not connect by timing out or what not. This may be caused by the firewall. If you are using Windows Firewall, find and enable the inbound rule for World Wide Web Services. The port should be 80.

DNS

When on another computer, you may not want to type in 192.168.1.23 just to get to connect to your service. You may want to type in http://MySite instead. This will be controlled in a DNS Server. The DNS settings should be located in your router firmware.

Wednesday, September 19, 2012

[.NET/IIS] Tired of opening up a web service just to run it? Use Virtual Directories!

Alright, so lately I've been working a lot with web services and one the major gripes is actually running the darn things. At first, I always had to open VS2010, open my project, and then right click the solution that contains the svc, and click view in model browser. Being that I'm currently on windows XP, this whole procedure was not pleasant. Then I found out how to activate it through a batch script. The batch script looked like this:


@echo off

::WEBSERVER PATH
set webserverpath="C:\Program Files\Common Files\Microsoft Shared\DevServer\10.0\WebDev.WebServer40.EXE"

::WEBSERVICE PATHS
set webservice="C:\Workspace\MyWebService"

::COMMANDS
start "" %webserverpath% /port:3934 /path:%webservice%

To add more web service solutions, I just had to new variables and commands under WEBSERVICE PATHS and COMMANDS. Although, this saved me A LOT of time compared to the first method, it was still a hassle just click the little bugger. Also, when a web project gets deployed on a server, there may be instances (maybe all instances) where the web services are needed to be running at all times. So if you configure your localhost to be the same way, then there shouldn't be any hassles when deploying code on the server (for example, the need to change the web.config).

So here's how to do it:

Go to your IIS. So under where you have Web Sites, and maybe Default Web Site, add a new virtual directory. Assign the path to where your .SVC file or web service project is located. Now go back to your web app in VS2010, and open up the web.config. You may need to add or edit the necessary endpoints. Right now, my endpoint address looks like, "http://localhost/MyWebService/WebService.svc". After that, you should be good to go and should never have to run or edit your webservice....hopefully...yea

Edit: If you're running .NET 4, make sure your application pool for your web service is also version 4 in the IIS and ASP.Net tab of your service.

Thursday, May 10, 2012

[C#] Visual Studio Database woes...

Site is on one domain and I need to remotely connect to an SQL Database.
- In the Server Explorer, connecting to the SQL Database uses Windows Authentication.
- With Windows Authentication on, produces untrusted zone error.
- With it off, produces failed login error.

The fix?
- Connection string format:
"Data Source=<source>;Persist Security Info=False;Initial Catalog=<initial_catalog>;Trusted_Connection=Yes"

- In Web.Config, add
<configuration>
   <system.web>
       <identity impersonate="true"/>

---------------------------------------------------------------------------------------------

Sql Db Type is numeric, but how to express it in C#?
- Use Decimal

----------------------------------------------------------------------------------------------

How to express VarChar(MAX) in C#?
- SqlDbType.VarChar, -1

----------------------------------------------------------------------------------------------