I have 2 sites.
I also have a webservice.
You can see this in action when I load countrynames in the cascading dropdown on: http://www.mydomain.com/trouwlocaties/zoeken-uitgebreid
However, the same webservice throws an error on: http://otherdomain.com/weddingvenues/search-advanced
As you can see the dropdown shows 'method error -1' and in my Chrome console I see: 500 (Internal Server Error), where the client tries to GET the .asmx service, where on toptrouwen it uses POST (which is as I believe what's supposed to happen and also more secure).
This is the GetCountries webservice:
<System.Web.Script.Services.ScriptService()> _
<System.Web.Services.WebService(Namespace:="http://tempuri.org/")> _
<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
<ToolboxItem(False)> _
Public Class geolocation
'<System.Web.Script.Services.ScriptService()> _
'<WebService(Namespace:="http://tempuri.org/")> _
'<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
'<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Inherits System.Web.Services.WebService
<WebMethod()> _
Public Function GetCountries(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
Dim values As New List(Of CascadingDropDownNameValue)
Dim myConnection As SqlConnection = GetConnection()
Dim cmd As New SqlCommand(String.Format("SELECT id,name as title FROM country order by title asc", Threading.Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName), myConnection)
Try
myConnection.Open()
Dim reader As SqlDataReader = cmd.ExecuteReader
Dim CountryName As String
Dim CountryID As Integer
While reader.Read
CountryName = reader("title").ToString
Int32.TryParse(reader("id"), CountryID)
values.Add(New CascadingDropDownNameValue(CountryName, CountryID.ToString))
End While
Catch ex As Exception
Finally
myConnection.Close()
End Try
Return values.ToArray
End Function
End Class
First I tried adding this to my web.config:
<system.web>
<webServices>
<protocols>
<remove name="Documentation"/>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
</system.web>
After doing that, I receiving this in my Chrome console:
Uncaught SyntaxError: Unexpected token <
Where apparently the result was not interpreted as XML, but my guess is JSON. After some Google searches I believed this had to do with the MIME type, but I never found out how to change that to XML for this service.
So I continued searching and found something else, I was reading these posts:
http://social.msdn.microsoft.com/forums/en-us/asmxandxml/thread/F80BDA62-C87A-4BDA-8CB1-F2CFAD1C8891
Uncaught SyntaxError: Unexpected token < -- in jQuery ajax
Where apparently it might be a 'cross-domain issue'.
So I ended up with creating these files:
clientaccesspolicy.xml
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="*">
<domain uri="*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
crossdomain.xml
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<?xml version="1.0" ?>
<cross-domain-policy>
<allow-access-from domain="*" />
<allow-access-from domain="*.otherdomain.com" secure="false" />
</cross-domain-policy>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="GetCountries" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://www.mydomain.com/geolocation.asmx"
binding="basicHttpBinding" name="GeoLocation" />
</client>
</system.serviceModel>
</configuration>
In the first example link that user also added attributes bindingConfiguration="DashboardServiceSoap" and contract="DashboardService.DashboardServiceSoap", but I have no idea what I would have to fill in there for my case.
I'm still stuck, I don't know what is the right track and how to configure my setup.
UPDATE 21-06-2013
Updated my web.config with:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
I also tried the following 4 configurations:
<System.Web.Script.Services.ScriptService()> _
<System.Web.Services.WebService(Namespace:="http://tempuri.org/")> _
<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
<ToolboxItem(False)> _
Public Class geolocation
Inherits System.Web.Services.WebService
Scenario 1 and 2 With this method definition:
<WebMethod()> _
Public Function GetCountries(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
Scenario 1: WITH protocols section in web.config
<webServices>
<protocols>
<remove name="Documentation"/>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
Works correct on .nl domain
Throws method error -1 on .com domain. Chrome Console shows: Uncaught SyntaxError: Unexpected token < GetCountries:1
Scenario 2: WITHOUT protocols section in web.config
Works correct on .nl domain
Throws method error -1 on .com domain. Chrome Console shows: GET http://www.otherdomain.com/geolocation.asmx/GetCountries?knownCategoryValues=%22%22&category=%22Country%22&callback=Sys._jsonp0 500 (Internal Server Error) ScriptResource.axd:7773
Scenario 3 and 4 with this method definition:
<WebMethod()> _
<ScriptMethod(UseHttpGet:=True, ResponseFormat:=System.ServiceModel.Web.WebMessageFormat.Json)> _
Public Function GetCountries(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
Scenario 3: WITH protocols section in web.config
<webServices>
<protocols>
<remove name="Documentation"/>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
Throws method error 500 on .nl domain. Chrome Console shows: POST http://www.mydomain.com/geolocation.asmx/GetCountries 500 (Internal Server Error) catcher.js:197
Throws method error -1 on .com domain in dropdown. Chrome Console shows: Uncaught SyntaxError: Unexpected token < GetCountries:1
Scenario 4: WITHOUT protocols section in web.config
Throws method error 500 on .nl domain. Chrome Console shows: Failed to load resource: the server responded with a status of 500 (Internal Server Error)
Throws method error -1 on .com domain in dropdown. Chrome Console shows: GET http://www.otherdomain.com/geolocation.asmx/GetCountries?knownCategoryValues=%22%22&category=%22Country%22&callback=Sys._jsonp0 500 (Internal Server Error)
Also I'm not explicity calling the .asmx from script, I let the cascading dropdown do that work for me. Like so:
<asp:DropDownList ID="ddlCountries" CssClass="textbox" AutoPostBack="true" runat="server"></asp:DropDownList>
<cc1:cascadingdropdown ID="cddCountries" runat="server" Category="Country" Enabled="True" LoadingText="<%$Resources:Glossary,loading %>" PromptText="<%$Resources:Glossary,country_choose %>"
ServiceMethod="GetCountries" TargetControlID="ddlCountries">
</cc1:cascadingdropdown>
code-behind
cddCountries.ServicePath = "http://www.mydomain.com/geolocation.asmx"
I don't know if the fact that I'm using these pre-defined elements have anything to do with my issue, and I could better call the .asmx service via script myself and fill the dropdowns. If so: I have no idea how to do so.
You are correct that this is a cross-origin problem. There are several ways of handling this:
You can turn your web service into JSONP as long as the data that needs to go to the web service is not terribly large. The data coming from the service can be as large as you like though. By not terribly large, it must be about 2k characters or less - you can calculate the amount of data that can be sent in one JSONP request by knowing that it is sent as part of the get request from the src attribute of the script tag.
Here's a good SO answer on JSONP with which you may already be familiar:
What is JSONP all about?
UPDATE
Here's an example of doing JSONP in VB.NET:
http://www.sattsoft.com/tutorials/contents/1/14/cross-domain-call-using-ajax-jquery-jsonp-and-vb-net-web-service.html
You can create a sub-domain of www.wunderweddings.com, call it perhaps "api.www.wunderweddings.com" and use DNS to point that subdomain to the right place using either an A or CNAME record. Then you would embed a tiny (invisible) iframe into your client-side page that would point to this new api host (be sure to specify the src as "//api.www.underweddings.com" so as to match http/s of the containing page), and use javascript within the iframe to promote its document.domain to www.wunderweddings.com which you may do through script injection but its easier to just have that page on the server provide the script to do it, then you can communicate freely between the iframe which points to your api and the page containing the iframe which is at www.wunderweddings.com. So code inside the iframe would go access the web service for you, get the data, promote its document.domain, and notify the containing page.
If you know postMessage is always available on your clients (probably not though) you can do the above without changing the document.domain.
Points 2 and 3 above probably sound like a hassle! Especially if you intend to expand the web services you offer and/or the number of domains accessing that service. If so, I would very highly recommend utlizing EasyXDM, it is a wonderful and quite powerful library for doing client-side cross-domain RPC:
http://easyxdm.net/wp/
EasyXDM provides fallbacks from postMessage if it isn't available such as communication through the hash or the name attribute, among a few other things.
You can fix the crossdomain.xml. Now here's where I'm a little rusty but I'll give you my best guess:
UPDATE
You want your crossdomain.xml to like this:
<?xml version="1.0" ?>
<cross-domain-policy>
<allow-access-from domain="*" />
<allow-access-from domain="*.wunderweddings.com" />
</cross-domain-policy>
The first child of the "<cross-domain-policy>", that is "<allow-access-from domain="" />" will make it completely unrestricted whereas "<allow-access-from domain=".wunderweddings.com" />" will make it so only wunderweddings.com and subdomains will be allowed to do a crossdomain call by the browser. You don't need both "allow-access-from" tags, but at least one of them.
I'm not sure why that configuration stuff is in there, it shouldn't be. I completely failed noticing that the first time around, that is almost certainly your problem. Also make sure that crossdomain.xml is being served from the other server, the one with the web service.
So just to clarify, that crossdomain.xml should not have that extra XML at the bottom, the <onfiguration>...</configuration> tags and everything inside of it, all of that is leaking in from someplace and shouldn't be inside crossdomain.xml
FINAL UPDATE
For those reading this answer who have a similar problem, Floran discovered the problem with the invalid character:
this had to be added to the top of the page:
<asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="server">
<Services>
<asp:ServiceReference Path="geolocation.asmx" />
</Services>
</asp:ScriptManagerProxy>
Related
I am using asp.net core 3.1 and receiving values from URL. Its working fine but when I add "+" sign as a part of URL, it gives 404.
Example : localhost:9000/api/get/%2B12/values
+ is a special character. It should ideally be should be URL encoded as %2B.
Turns out it's not really required though (like in the screenshot below) but I still recommend it. (See: URL encoding the space character: + or %20?)
Here's a working example controller:
[ApiController]
public class ExpController : Controller
{
[Route("/api/exp/{arg}/values")]
public IActionResult Test(int arg) =>
Ok($"The arg is: {arg}");
}
Note how the route parameter is a int. For more complex values (other than just 12, +12, -12; eg: 12+12) the route will need to be a string instead.
version above IIS7 will refuse to request the URL contains symbols such as '+' by default. The following modifications are required. You need add the following nodes in web.config:
<system.webServer>
<security>
<requestFiltering allowDoubleEscaping="true"/>
</security>
</system.webServer>
But now the .net core project does not have web.config to configure IIS options. You need to go to the location:
vs project location /.vs/config/applicationhost.config to add the above node.
Note that the .vs folder is a hidden folder and needs to be set visible.
Option 1 :
Mess with config to bypass request validation / allowDoubleEscaping (Asp.Net)
You need to be aware for certain risk/vulnabilirities described here:
https://stackoverflow.com/a/53621095/4798459
.netcore :
Since this issues is related to IIS, not your solution. You need to handle a web.config
Create a new web.config on the root of your project.
Right click, properties, set "Copy to Output Directory" to "Copy Always"
When you publish a .net core app, a "basic web.config" file is created. (For iis)
You need to copy the content of the "basic web.config".
You can find the auto-generated web.config file:
Where your app is already published (local server?)
You can also publish your api temporarly to a random path on your PC, see details here https://docs.devexpress.com/OfficeFileAPI/401445/dotnet-core-support/publish-net-core-application)
The web.config should like so, i added the tag with a a commentt
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<!-- XML node <security> is added to allow allowDoubleEscaping and add support for + paremeter in a route. Risk:https://stackoverflow.com/a/53621095/4798459 -->
<security>
<requestFiltering allowDoubleEscaping="true"></requestFiltering>
</security>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments="[.\SolutionName.Namespace.dll]" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
</system.webServer>
</location>
</configuration>
Make sure that the step 2 is done before publishing your app otherwise it wont work.
Not tested with iisexpress
Option 2
Change pramater type in the api. Intead of being on the route, use a queryString instead
Option 3
Custom solution for request filtetring /routing, which i don't have any example, and seems a bit "over the top".
Option 4, to avoid:
Use an other solution for encoding / decoding special caracter (I have not tried)
https://stackoverflow.com/a/55637235/4798459
I am trying to implement a Custom HttpHandler (for the first time), I have been given a tutorial to follow but couldn't get it to work. I then found another tutorial but couldn't get that to work, they are both giving me the same error message.
The custom handler is to protect people from downloading certain file types, although i think the error is somekind of configuration problem as I can't get the website to work at all once I add the httpHandlers to the Web.Config file.
Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.
Parser Error Message: Could not load type 'FileProtectionHandler'.
Source Error:
Line 47: </compilation>
Line 48: <httpHandlers>
Line 49: <add verb="*" path="*.pdf" type="FileProtectionHandler"/>
Line 50: </httpHandlers>
If you require more code please let me know.
Thanks for any help. J.
<%# WebHandler Language="VB" Class="FileProtectionHandler" %>
Imports System
Imports System.Web
Imports System.Web.Security
Imports System.IO
Imports System.Web.SessionState
Public Class FileProtectionHandler : Implements IHttpHandler
Private Function SendContentTypeAndFile(ByVal context As HttpContext, ByVal strFile As [String]) As HttpContext
context.Response.ContentType = GetContentType(strFile)
context.Response.TransmitFile(strFile)
context.Response.[End]()
Return context
End Function
Private Function GetContentType(ByVal filename As String) As String
' used to set the encoding for the reponse stream
Dim res As String = Nothing
Dim fileinfo As New FileInfo(filename)
If fileinfo.Exists Then
Select Case fileinfo.Extension.Remove(0, 1).ToLower()
Case "pdf"
If True Then
res = "application/pdf"
Exit Select
End If
End Select
Return res
End If
Return Nothing
End Function
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
context.Response.ContentType = "text/plain"
context.Response.Write("Hello World")
End Sub
Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
End Class
I had similar problem. Solution was in root namespace defined in properties.
In my code I do not have namespace, so in this case you need to use
type="[namespace or root namespace].[your class name]"
Try filling out the namespace that the class lives in as well as the assembly it's built to.
Something like this
<add verb="*" path="*.pdf" type="FileProtectionHandler, Beswick"/>
or possibly this
<add verb="*" path="*.pdf" type="Beswick.FileProtectionHandler, Beswick"/>
or this
<add verb="*" path="*.pdf" type="Beswick.FileProtectionHandler"/>
Just had the same problem adding a new IHttpHandler to an existing project. The handler I added had build action property "Content" rather than "Compile". Changing it to compile fixed the issue
.NET 4.5 WebForm ,it was fixed for me after adding the ProjectName.ClassName
<httpHandlers>
<add verb="*" path="scripts/*" validate="false" type="ProjectName.NoAccessHandler"/>
</httpHandlers>
and I have extra part not positive if it actaully do anything under system.webServer -> Handlers I have this
<Handlers>
<add verb="*" path="scripts/*" name="NoAccessHandler"
preCondition="integratedMode" type="NoAccessHandler"
resourceType="Unspecified"/>
</Handlers>
I've just come back to this issue after a lengthy break from it. I'm not sure if i've got it fully working as yet as from first testing it's not protecting the file if a user isn't logged into the website, but I am no longer getting the error message.
I found the fix to the problem here: HttpHandler 101 FAIL
If none of these answers works, and your project is a Web Appliccation (as opposed to a Web Page as in HttpHandler 101 FAIL), check the build output path. I had recently changed my platform to x86, which changed Properties ->Build -> Output path to
bin\x86\Debug
I changed this back to
bin\
and it worked.
I encountered a similar error while debugging an Azure Web App locally (the error persisted when deployed to Azure). I suspect that the error has something to do with locally stored configuration/compilation files, which are not updated properly even when the solution is cleaned and rebuilt. I had two different projects which produced identically named dll's (albeit to different locations), not sure if this had any effect on the issue.
After lengthy experimentation, the solution for me was to go to Solution Explorer in Visual Studio, right-click on the project --> Properties. Under the Application tab, change the Target framework to something else (I changed 4.6 to 4.6.1). You will get a prompt saying that the project will be reloaded, click OK. After reload, do the same thing reverting back to your original version (4.6 for me). This fixed the issue for me.
It would be nice to understand the root cause of the issue. I still get the error sometimes when reopening the project, and I have to go through the above steps again.
Changing the order and keeping as below in config file fixed my issue.
<system.webServer>
<handlers>
<remove name="traceverbhandler" />
<remove name="optionsverbhandler" />
<add name="extensionlessurlhandler-integrated-4.0" path="*." verb="*" type="system.web.handlers.transferrequesthandler" />
<remove name="extensionlessurlhandler-integrated-4.0" />
</handlers>
</system.webServer>
I am getting a Internal Server 500 error after deploying an application that has compiled without errors on my local machine. The server that the application is deployed on has a ton of security so I need to specify read and write access for every directory. This application uses windows authentication and a web service to populate drop down boxes via a proxy. I think there might be an issue connecting to the web service or an issue with the read/write security on the files, or an issue with the active directory authentication.
I edited the web.config so that it would display more information as to the cause of the error with the following code:
<system.web>
<customErrors mode ="Off"></customErrors>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.0" />
<trace enabled="true" pageOutput="true" />
<authentication mode="Windows"/>
<authorization>
<allow roles="alg\ADMIN_USER" />
<deny users="*" />
</authorization>
<client>
<endpoint address="http://63.236.108.91/aCompService.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IAcompService" contract="aComp_ServiceReference.IAcompService"
name="BasicHttpBinding_IAcompService" />
</client>
I am now getting the following Error:
500 - Internal server error.
There is a problem with the resource you are looking for, and it cannot be
displayed.
I would like to see the stack trace with the source of the error.
What am I supposed to put in the web.config file so it displays the full stack trace?
What needs to be changed on the website from locally run to deployment?
Update- The deployment guy lifted some security read/write restrictions and now I get
Parser Error Message: The connection name 'ApplicationServices' was not found in
the applications configuration or the connection string is empty.
To get rid of the error, I removed the AspNetSqlRoleProvider declared on Line 72 and still
got an error. I then removed the AspNetWindowsTokenRoleProvider and all the provider info
and got the following Error:
Exception message: Default Role Provider could not be found.
Our hosting is done all remotely but the server guy can login to the local webserver remotely. It looks like the server guy didn't post the files in the right place. Now, I now get the error:
There is a problem with the resource you are looking for, and it cannot
be displayed.
Any ideas on how to fix these issues?
Thanks for looking!
Do you have a web.config at another location in the application's folder hierarchy that could be overriding the change you're making? I've seen confusion before when devs have copied a web.config up a level to retain a copy of it while making test changes.
That can be a source of much head-scratching.
Perhaps using impersonation should help?
I added the following in web.config:
<authentication mode="Windows"/>
<identity impersonate="true"/>
I added WriteToEventLog code so that I can track errors in the event log by the method.
Catch Ex As Exception
WriteToEventLog(Ex.Message, "GetCarriers-Method", EventLogEntryType.Error, "aComp-utility")
Catch ex As Exception
WriteToEventLog(ex.Message, "GetMarketingCompanies-Method", EventLogEntryType.Error, "aComp-utility")
Perhaps adding a TraceListenerLog should help?
Reference MSDN for more info on this code. I added the following in web.config:
<configuration>
<system.diagnostics>
<trace autoflush="false" indentsize="4">
<listeners>
<add name="myListener"
type="System.Diagnostics.EventLogTraceListener"
initializeData="TraceListenerLog" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
should i also add the following on default.aspx.vb ?
Overloads Public Shared Sub Main(args() As String)
' Create a trace listener for the event log.
Dim myTraceListener As New EventLogTraceListener("myEventLogSource")
' Add the event log trace listener to the collection.
Trace.Listeners.Add(myTraceListener)
' Write output to the event log.
Trace.WriteLine(myTraceListener)
End Sub 'Main
I was able to over come this same problem by making a copy of my config file and then removing one segment and then testing the results one step at a time. What I discovered is that after I removed my handelers it worked fine.
I would like to have a variable defined in my web.config that I can use in multiple places within my web.config file (and other config files). It's probably easier to explain by example ...
web.config
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="AuthServiceEndPoint" value="any_old_name_i_like"/>
</appSettings>
<system.web>
...
<system.serviceModel>
<client>
<endpoint
address="net.tcp://localhost/AuthService"
binding="netTcpBinding"
contract="MyServices.Contracts.IAuthService"
name="#{AppSettings.AuthServiceEndPoint}"
bindingConfiguration="netTcpBindingConfig"
/>
</client>
</system.serviceModel>
</configuration>
windsor.config
<?xml version="1.0" encoding="utf-8" ?>
<castle>
<components>
...
<component
id="AuthProvider"
service="MyServices.Client.IAuthProvider, MyServices.Client"
type="MyServices.Client.AuthProvider, MyServices.Client"
lifestyle="transient">
<parameters>
<endpoint>#{AppSettings.AuthServiceEndPoint}</endpoint>
</parameters>
</component>
</components>
</castle>
Is this possible?
Edit (a bit more information)
I already have the ability to access the AppSettings from my windsor.config file (which is actually processed by castle windsor and a custom XmlInterpreter.
The real question is can I do this in my web.config?
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="AuthServiceEndPoint" value="any_old_name_i_like"/>
</appSettings>
<system.web>
...
<system.serviceModel>
<client>
<endpoint
address="net.tcp://localhost/AuthService"
binding="netTcpBinding"
contract="MyServices.Contracts.IAuthService"
name="#{AppSettings.AuthServiceEndPoint}"
bindingConfiguration="netTcpBindingConfig"
/>
</client>
</system.serviceModel>
</configuration>
ie - access variable in my <appSettings> from other parts of my web.config file.
Off the top of my head, I wonder if you might be able to do this with T4? I'm thinking that perhaps you could define a template which parses Web-Template.config and outputs Web.config? Of course, this only works for a single file.
You can use NAnt or MSBuild for this. You do need separate configuration files for both, but when you build your project they can automatically do transformations on your Web.config and other configuration files.
Not that I can think of. You could do your configuration in C# in global.asax.cs instead of the xml file.
Alternatively, have your web.config edited by your build process to replace all these values. FinalBuilder has a neato "Edit XML File" action that uses XPath quite well to do this, and FinalBuilder does have variables. Problem solved. This is how I do my builds at work.
Here I go answering my own question again :-S
I solved this by writing a NetTcpServiceLocator ...
public interface INetTcpServiceLocator
{
EndpointAddress GetAddress(Type serviceType);
}
... along with a custom config section handler which also implements the above interface and reads in the following config section ...
<services>
<service contract="My.Services.TestService.Contracts.ITestService" address="net.tcp://localhost/TestService" />
</services>
Then I created a proxy for each service ...
public class TestServiceProxy : ITestService
{
public SomeInformation GetSomeInformation(SomeParams #params)
{
using (var factory = new NetTcpServiceFactory<ITestService>())
{
var service = factory.Service;
return service.GetSomeInformation(#params);
}
}
}
My Controller has a dependency on a Service, which has a dependancy on ITestService. All this is glued together with Castle Windsor and by using property dependency injection.
So, my controller calls it's Service, which in turn calls the ITestService (in this case a proxy, which gets it's endpoint from the custom section handler).
The custom section handler (which is also the INetTcpServiceLocator) has a windsor lifestyle of "perWebRequest", so it gets called by the framework and web.config is read into an array in memory. When the service proxy is called, it then just pulls the relevant endpoint based on the contract type.
It's all driven by the type of the contract, so there is no need to have any variables in web.config anymore.
I've gone for a code based solution, as I don't use a build process locally, only when I submit my code to subversion does the build process kick in on our build server.
I am working on a website, in which I am retrieving XML data from an external URL, using the following code
WebRequest req = WebRequest.Create("External server url");
req.Proxy = new System.Net.WebProxy("proxyUrl:8080", true);
req.Proxy.Credentials = CredentialCache.DefaultCredentials;
WebResponse resp = req.GetResponse();
StreamReader textReader = new StreamReader(resp.GetResponseStream());
XmlTextReader xmlReader = new XmlTextReader(textReader);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(xmlReader);
This code is working fine on my development PC (Windows XP with .Net 3.5)
But when I deploy this code to IIS (Both at Windows XP and at Windows Server 2003) it's giving me following error
"The remote server returned an error: (407) Proxy Authentication Required."
Sometimes it gives me
"The remote server returned an error: (502) Bad Gateway."
Following code is from my web.config
<system.net>
<defaultProxy>
<proxy usesystemdefault="False" proxyaddress ="http://172.16.12.12:8080" bypassonlocal ="True" />
</defaultProxy>
</system.net>
Please help me ?
[Edit]
Even when i run the website for devlopment PC but through IIS it gives me error "The remote server returned an error: (407) Proxy Authentication Required."
But when i run website from Microsoft Devlopment server, it is running fine
#Mohit Agarwal
Many thanks for suggesting adding ' useDefaultCredentials="true" ', you're a star!
I have been trying to get the .NET library for the Google Data API sample exe's working for weeks without success. Adding your suggestion fixed my problem and I now get a connection instead of 407 Proxy Authentication Required.
speadsheet.exe.config contents need to be:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.net>
<defaultProxy useDefaultCredentials="true">
<proxy usesystemdefault="true"/>
</defaultProxy>
</system.net>
</configuration>
In my case NOT as Google suggest:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.net>
<defaultProxy>
<proxy usesystemdefault="true"/>
</defaultProxy>
</system.net>
</configuration>
http://code.google.com/p/google-gdata/wiki/WebProxySetup
It might be helpful for someone out there finding this via Google that you can actually put this to use in .NET applications that may not have their own AppName.exe.config file yet (or you can modify it if so). We use NextGen EPM (medical scheduling / billing) and their credit-card processing system kept getting stuck at our proxy server because it wouldn't pass the credentials. I made an EXEName.config file (NextGenEPM.exe.config in this case) containing the snippet above:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.net>
<defaultProxy useDefaultCredentials="true">
<proxy usesystemdefault="true"/>
</defaultProxy>
</system.net>
</configuration>
Success! This allowed me to resolve the issue without mucking around in our proxy server, which is adamantly configured to require authentication and we'd rather not compromise that.
Does it work when you change the snippet in web.config to:
<system.net>
<defaultProxy useDefaultCredentials="true">
<proxy usesystemdefault="False" proxyaddress ="http://172.16.12.12:8080" bypassonlocal ="True" />
</defaultProxy>
</system.net>
This is probably caused by the account that IIS is running under not having the appropriate permissions to get through the authenticating proxy.
When you run it on your development PC, you are running it as your logon, which I assume has permissions to get through the proxy. When running inside IIS, it is not running as you, and so probably cannot get through the proxy.
You could either give the IIS user permissions to get through the proxy (which will be unlikely to work in a domain environment as the IIS user will be a local user the machine), or configure your application to run as a network user with permissions to get through the proxy.
This can be done by either getting IIS to run as a domain user (I wouldn't recommend this approach), or by configuring you application to run as a domain user using web.config (see this article for more info on how to do this).
Beneath the root <configuration> element in app.config or Web.config:
<system.net>
<defaultProxy useDefaultCredentials="true">
<proxy usesystemdefault="True"/>
</defaultProxy>
</system.net>
Try this one if you want to specify the proxy details
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.net>
<defaultProxy enabled="true" useDefaultCredentials="true">
<proxy proxyaddress="http://<ProxyServer>:<port>"
usesystemdefault="False"
bypassonlocal="True"
autoDetect="False" />
</defaultProxy>
</system.net>
</configuration>
Cheers!
We spent a long time struggling with this issue and updated our app.config to use default credentials as specified in the answers above.
However, it still didn't work!
Following a lot of pain we discovered that our app.config was not being included automatically with our click once application.
Simple mistake caused extreme head wreckedness!!!