Setting variables in web config for web service consumption - asp.net

I did a couple google searches about this and am not finding anything, so I thought I'd ask here.
I'm working on our internal CMS and I noticed that we're getting live data back when doing debugging because of our web services instead of the dev data that I wanted. It doesn't do this on our dev CMS website, but we're trying to do all our development on localhost. Is there any way to set up an environment variable in our web config for the URL so that the CMS points to the dev database instead of live database that is referenced in the wsdl files?

You can use the appSettings portion of the web config to for configuration information.
In the configuration section of the Web.config you will find the appSettings section:
<appSettings>
<add key="Key" value="Some Value"/>
</appSettings>
In code you can read in the value like this:
var someValue = ConfigurationManager.AppSettings["Key"];

+1 for Dan's method of storing the URL. To use this URL at runtime just update the URL property of your web service proxy object with the value from your web.config.
MyClientClass o = new MyClientClass();
o.Url = varFromWebConfig;
o.MyWebMethod();

Actually, one of my coworkers suggested an alternate way of solving this issue which seems even better to me: fixing it server-side, rather than client side like I've been trying and has been suggested here. His suggestion was to create a subdomain in IIS on all of our servers that points to the web service folder and then put host files for the appropriate web server on my local machine. This seems like the ideal solution to me since it wouldn't require changing all the current web service proxy objects like the client side solution would, just the web service consumption within App_WebReferences.

YES!!! USE Web.config transforms
Web.config contains the configuration that will run in your IDE while debugging:
<configuration>
<appSettings>
<add key="Service.Name" value="http://debugserverURI/Service.asmx"/>
</appSettings>
</configuration>
On publish in "Release" mode, transforms in Web.Release.config will be applied:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<appSettings>
<!--point to production server -->
<add key="Service.Name" value="http://PRODUCTIONserverURI/Service.asmx"
xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
</appSettings>
</configuration>
You can do the same for Web.[whatever_build_you_want].config, if you support both test and prod servers.

Related

How will be visual studio deployment scnerio

I consumed about deployment for my projects. For example I am developing a asp.net web api or asp.net mvc project on visual studio. I use local database and local file usernames and password for ssl. I finish the development and publis it on my local iis server and see the working application. After local iis test, I load it to server but sometimes forget the change web.config settings, connectionstrings, ssl certificate paths and password. So the working server application that users accessed fails. How can I solve this problems?
What I do is I replace the configuration in the Web.Release.config using Transform
So if for example in my Web.config I have the following connection string:
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\sample.mdf;Initial Catalog=sample;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>
In my Web.Replace.config I update the connectionString for production like this:
<connectionStrings xdt:Transform="Replace">
<add name="DefaultConnection" connectionString="SERVER_CONNECTION" providerName="System.Data.SqlClient" />
</connectionStrings>
Though keep in mind that the Transformation that I did in Web.Replace.config only applies when you publish your web app. You won't be able to test it locally by just running your application in Debug/Release mode
You should implement Web.Config transformation. Check this MSDN link for more information.
Just to give an overview - by implementing Web.config transformation, your project will have different Web.Config file (For example, Web.config, Web.Live.config, Web.PreProd.Config, etc), i.e., each different file for diffrent build configurations. The main web.config should remain as it is. Its just the other config files where you will need to specify the configurations which you want to overwrite. Once done, if you publish with a particular build configuration, then the newly generated web.config (in publish folder) should have all configurations from web.config + the differences you would have specified in the transformed file for that build configuration.

Is there a "release" configuration for ASP.NET Web Sites?

I use Visual Studio for Website development (VS 2010 Ultimate and VS 2012 Professional). To be more specific, I created this website by File > New Web Site, so I do not believe this is a project.
While developing the website, I have debug="true" enabled in the web.config file. When I publish, I manually change to debug="false".
<configuration>
<system.web>
<compilation debug="true" strict="true" explicit="true" targetFramework="4.5">
</system.web>
</configuration>
There are two config files in the solution: "web.config" and "web.Debug.config".
This is what the various forum articles and "Programming ASP.NET" books say to do, but I wonder if there is a way to have debug="true" for local development and automatically switch to debug="false" when using Build > Publish Web Site so I don't have to manually change the web.config file?
According to this forum answer, "There is no way to have a Release configuration for your website."
Keeping in mind that this is a Web Site and not a project, it looks like adding another config based on comment suggestions might not be possible. A possibly valid answer is "no, it is not possible in this context."
Is there another way to achieve the intended outcome without using the current workaround of manually changing the debug setting?
Sorry, it's related to it being a "web site" type project, which aren't compiled:
Configuration of publishing an ASP.NET web site
To quote the previous responder above:
"Web Site projects don't have the Release configuration available, but it makes no difference since they are not compiled. Web Application projects, on the other hand, do get compiled and have both configurations available."
According to the available references, for "ASP.NET Website" it is not possible to have a separate release configuration.
So the answer to the posed question is no: it is not currently possible. Manually changing the debug attribute when you publish and then changing it back is the only option in that case.
How can you proceed? If you really need to have a release configuration and a debug configuration, the a possible option is Converting a Web Site Project to a Web Application Project. While not a direct answer to the presented question, it is an alternative.
For some projects I've set up an Environment appSetting and scoped all other keys off of that Environment.
For instance:
<add key="Environment" value="Development"/>
<add key="Development.Title" value="My Dev App"/>
<add key="Production.Title" value="My Production App"/>
<connectionStrings>
<add name="DbContext.Development" connectionString="Initial Catalog=DatabaseDev;...."
providerName="System.Data.SqlClient" />
<add name="DbContext.Production" connectionString="Initial Catalog=DatabaseProd;...."
providerName="System.Data.SqlClient" />
</connectionStrings>
Then you would create a Configuration class that would pull appSettings and connectionStrings by looking for:
appSetting
string.Format("{0}.Title", ConfigurationManager.AppSettings["Environment"])
connectionString
string.Format("DbContext.{0}", ConfigurationManager.AppSettings["Environment"])
Not perfect but this will let you only have to replace one web.config value instead of a bunch without the help of the Publish config transform.

Allow only one web app to call a web service

How to configure that a web service only be called by one specific web application? Both ones are in the same IIS server.
Framework: 2.0
I think that setting web.config of web service would be enough.
On this example, I'm setting web.config of web service. Web service will be called only by one IP address (127.0.0.1 is IP of IIS Server):
<location path="resources">
<system.webServer>
<security>
<ipSecurity allowUnlisted="false">
<clear/>
<add ipAddress="127.0.0.1"/>
</ipSecurity>
</security>
</system.webServer>
</location>
Would it be ok?
If it's only being called by one specific application on the same server, a Web Service may not be the right choice. It would make more sense for the code to be within a class in the same app. Web services are best suited for situations where multiple apps need to access the same functions.
That said, with IPV6 coming, the option you thought of won't work. If you're really just trying to limit requests to apps that come from the same sever, in you can put the following in code to check to see if it's coming from the local server:
if(Request.IsLocal)
{
//code here
}
For simplicity's sake, you can put the following in Application_BeginRequest in the global.asax file for the web services:
if(!Request.IsLocal)
{
throw new Exception("Only local requests are allowed");
}
This will effectively fend off anything not coming from localhost.

Custom Sharepoint webservice requires web.config to be "touched" regularly

We have a site running on MOSS 2007 which makes calls to custom web service asmx methods on the same domain from the client.
At first everything works fine, but after a bit of time has passed the service will start to fail with:
http://[domain]/_layouts/error.aspx?ErrorText=Request format is unrecognized for URL unexpectedly ending in %27%2FIsSuspectWaterLevel%27.
Interestingly enough
http://[Domain]/_vti_bin/Custom/CustomFunctionality.asmx?op=IsSuspectWaterLevel
is still available, but a call to
http://[Domain]/_vti_bin/Custom/CustomFunctionality.asmx/IsSuspectWaterLevel
will fail as described.
We've found that "touching" C:\Program Files\Common Files\microsoft shared\Web Server Extensions\12\ISAPI\ web.config will bring the webservice back to life.
The asmx file lives at
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI\ECan\MyECan_ComplianceWaterUsage.asmx
Any ideas of what might be going on here and how to resolve them?
Some extra detail:
App pool settings in case they're useful: http://i51.tinypic.com/x51qw.png
The following web.config settings are present in the root and sub directory hosting the asmx:
<system.web>
<webServices>
<protocols>
<add name="HttpSoap" />
<add name="HttpGet" />
<add name="HttpPost" />
</protocols>
</webServices>
...
</system.web>
We are calling the web service from javascript (jQuery). I've checked all the settings mentioned in this link and all match. I think calling from javascript may not be the culprit though as going directly to
[domain]/_vti_bin/Custom/CustomFunctionality.asmx/IsSuspectWaterLevel
with parameters supplied also fails with the same error - no javascript involved. Failing after a short period of time has passed, but works fine when web.config has just been "touched" again.
Thanks in advance for any help! Cheers, Gavin
I'm currently working on the same problem, and I think you barked the wrong tree.
The problem is, that in the ISAPI folder of SharePoint is a web.config with the following lines:
<webServices>
<protocols>
<remove name="HttpGet"/>
<remove name="HttpPost"/>
<remove name="HttpPostLocalhost"/>
<add name="Documentation"/>
</protocols>
</webServices>
The problem is, that the desired protocols POST and GET will be removed for the entire ISAPI folder and its subfolders. I also tried to reactivate the protocols via
<location path="[Path to my Web Service].asmx" allowOverride="false">
<webServices>
<protocols>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
</loaction>
in different places (machine.config, web.config of root folder, web.config app.config, ...), but it didn't last.
The only thing that worked, was, to change the "remove" items in the web.config of the ISAPI folder to "add" items.
But this has the nasty side effect, that the built-in web services, like "Lists.asmx" throw errors if you try to request their documentation pages...
If you can live with that, this would be your solution. I can't, so I still try to figure out a way to make my
<add name="protocol">
items persistent.
By the way: Also adding lockItem="true" to the <add/> items didn't do the trick...
Chris
It has been awhile since I have touched Sharepoint so this is a shot in the dark. If I remember correctly modifying anything in the web.config will restart the website in IIS. So what you may be seeing is IIS restarting the website that hosts the webservice putting it back into a good state.
Do you have the following in the web.config for the web application?
<webServices>
<protocols>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
This is a strange problem and hard to diagnose due to the number of occcurances of the 12 hives web.config protocols issue which would appear to resolve 99% of the cases of this issue.
There is another issue called URL rewriting that will cause this
problem.
Some reverse proxy devices can modify the path of a request (the
portion of the URL that comes after the hostname and port number) in
such a way that a request sent by the user to
http://www.contoso.com/sharepoint/default.aspx, for example, is
forwarded to the Web server as
http://sharepoint.perimeter.example.com/default.aspx.
This is referred to as an asymmetrical path. Windows SharePoint
Services 3.0 does not support asymmetrical paths. The path of the URL
must be symmetrical between the public URL and the internal URL. In
the preceding example, this means that the "/sharepoint/default.aspx"
portion of the URL must not be modified by the reverse proxy device.
Even more depressing is that microsoft knows about this and actively refuses to support it.
Ref: URL Rewrite + SharePoint = No Support
Also : SharePoint, url rewriter, WebServices
An inelegant workaround to this issue that works for us: We've swapped out the web service asmx end point for a web handler ashx endpoint. This doesn't suffer the same issue for some reason.
I'm guessing from this that there's some issue creeping in after a period of time which is causing urls to resolve incorrectly. I suspect that the / after the .asmx in the url is the curprit. The ashx endpoint implemented is working purely on url parameters and posted data.
Obviously this work around won't always be an option for others who might experience the same issue as we're loosing a lot of the rich web service functionality that's pre-baked in to an asmx endpoint.
Unfortunately I won't be able to test any other solutions that people might put forward from now on as we've moved away from the web service asmx approach. Sorry. Thanks for all the suggestions though - it's been very much appreciated!

Different configuration files for development and production in ASP.NET application

On a project I'm working on we have a web application with three configuration files;
Web.Config
Web.Config.TestServer
Web.Config.LiveServer
When we release to the test server, Web.Config is renamed to Web.Config.Development and Web.Config.TestServer is renamed to Web.Config, making that configuration active for the application.
It is quite onerous keeping three very similar configuration files up to date, and this system is used across a number of applications which are part of this project; not just the website.
The differences in configuration are most commonly local directories or paths, URLs, IPs, port numbers, and email addresses.
I'm looking for a better way.
While your approach seems tedious, I find it to be the best approach.
I used to keep all of my configurations in a single web.config file, and simply had the "production" section commented out.
Shortly after this I had to do a "hybrid" test where my lookup data was coming from the production server, but the new data was being inserted into the test database. At that point I had to start piece-mealing what parts of the configuration block to comment/uncomment, and it became a nightmare.
Similarly, we have our server administrators do the actual migration from test to production, and most of them aren't fluent enough in .NET to know how to manage the web.config files. It is far easier for them to simply see a .test or .prod file and migrate the proper one up.
You could use something like a database to store all your configurations, but then you're running into another layer of abstraction and you have to manage that on top of things.
Once you get the knack or the template of how your two (or three) configuration files will be setup, it becomes a lot easier to manage them and you can have your test server configuration get modified for some unique testing without much hassle.
If you have a db server in the mix, you can create a table that has the config, the property name, and the property value in it, then all you have to do is change one value in the web.config, the config name (dev, test, prod).
If you have different dbs for each config, then the only thing that's different is the connection string.
Use Config Transformation and there is a blog here about it.
http://blogs.msdn.com/b/webdevtools/archive/2009/05/04/web-deployment-web-config-transformation.aspx
Basically you create targets named web.{build configuration}.config. In each target file you write your transformation where you can add, delete and modify nodes and attributes. Example could be
web.staging.configss
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add name="personalDB"
connectionString="Server=StagingBox; Database=personal; User Id=admin; password=StagingPersonalPassword"
providerName="System.Data.SqlClient" xdt:Transform="Replace" xdt:Locator="Match(name)" />
<add name="professionalDB"
connectionString="Server=StagingBox; Database=professional; User Id=professional; password=StagingProfessionalPassword"
providerName="System.Data.SqlClient" xdt:Transform="Replace" xdt:Locator="Match(name)"/>
</connectionStrings>
</configuration>
You then execute the transform by calling MSBuild {project file} /t:TransformWebConfig /p:Configuration=Staging

Resources