I've got a asmx service that takes a single int parameter. I can open the URL to the service and see the service description screen. From here I can enter the query parameters into a form and invoke the web service.
Is there any way to invoke a web service directly from a URL/query string?
This doesnt work:
http://localhost:4653/MyService.asmx?op=MyWebMethod&intParameter=1
Any ideas? I'd really like to be able to do this from a standard link due to some deployment issues. Am I going to have to wrap the request in a normal aspx page?
You can decorate your method to allow HTTP GET requests, which should in turn do what you're looking for like so:
[WebMethod]
[ScriptMethod(UseHttpGet=true)]
public string MyNiftyMethod(int myint)
{
// ... code here
}
And edit the web.config :
<system.web>
<webServices>
<protocols>
<add name="HttpGet"/>
</protocols>
Then you'll be able to call this method like so:
http://mysite.com/Service.asmx/MyNiftyMethod?myint=12345
EDIT: Note that this method of performing GET requests does come with some security risks. According to the MSDN documentation for UseHttpGet:
Setting the UseHttpGet property to
true might pose a security risk for
your application if you are working
with sensitive data or transactions.
In GET requests, the message is
encoded by the browser into the URL
and is therefore an easier target for
tampering.
ASMX web services use SOAP. SOAP requests use only POST to invoke methods. You will need to generate a proxy client in your aspx page to invoke the web service. If you really need to use GET verbs to invoke web services you might need to use a different approach such as WCF REST.
Related
I would like the ability to turn on trace-level logging in nLog, on production, but only for the current web request.
In other words, I'd like to be able to do something like...
http://mywebsite.com?logeverything=true
... which would do trace-level logging, but only for that web request, not the hundreds of other requests that are happening at the same time. I'd also like the logs for that request to go to a different file than where the rest of the logging is going to. An acceptable alternative to a query string would be to turn on the trace-level logging but only if the web request is local.
I could write my own Logger class and override the nLog log methods to do something along these lines, but my web project uses a number of different assemblies and and switching all the projects to use a new logger class would be something of a pain.
Anyone doing anything like this?
This could be done without the need of wrappers.
Install also NLog.Web (or in the case of ASP.NET Core: NLog.Web.AspNetCore nd follow the installation tutorial
Create your trace logs in c#
Write to session it's your request
Filter your logs in the .config
<logger name="*" writeTo="myFile">
<filters>
<when condition="${aspnet-session:Variable=myRequest} != 1" action="Ignore" />
</filters>
</logger>
in this case I use the session, but you could also use ${aspnet-request-url} - but that makes the config a bit more complicated
I have a WCF service hosted in an asp.net application.
Here's the service (shortened):
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceContract(Name = Name, Namespace = Namespace)]
[ServiceBehavior(Name = Name, Namespace = Namespace)]
public class WcfMaintenanceFacade {...}
Here's hosting:
RouteTable.Routes.Add(new ServiceRoute("entity/maintenance/5.20", new ServiceHostFactory(), typeof(WcfMaintenanceFacade)));
And here's relevant config section:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
</system.serviceModel>
My service instantiates, the requests are coming in, and event HttpContext.Current is not empty.
There are two (major, for me) issues that I can't solve:
HttpContext.Current.Session is empty
Global.asax's Application_BeginRequest is never called
And yes, from the call stack it seems like the request is going through WCF activation pipeline, not ASP.net pipeline. So what am I doing wrong?
About the session, you handle it with OperationContext.Current.RequestContext instead of HttpContext.Current.Session.
HttpContext: Current is always null when accessed from within a WCF
service. Use
T:System.ServiceModel.OperationContext.Current.RequestContext instead.
Read more here: https://msdn.microsoft.com/en-us/library/aa702682.aspx
Application_BeginRequest are used by ASP.Net applications, but WCF works different from common web applications, thus BeginRequest could not be hit on each request.
The ASP.NET HTTP runtime handles ASP.NET requests but does not
participate in the processing of requests destined for WCF services
.... he WCF Service Model intercepts messages addressed to WCF
services and routes them through the WCF transport/channel stack
So, your problem can be related to this issue. This information is also available at the same link.
Hope it helps with your questions.
And the answer is simple (and, well, obvious):
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
Yes. RAMMFAR.
For me it is clear that these two technologies are not supposed to be working in the same application, and that's why they have two different pipelines. Service by the nature is an isolated thing. Now you just try to find a workaround, relying on the fact they both work on same IIS.
I would recommend you rather start from the goals, from what you want to achieve. If you need new service-like functionality integrated into native ASP.NET application you can
1) use ASMX services (will give you SAOP if you need it) and/or page methods
2) try to integrate WEB API in case you need JSON service.
I have an asp.net 4.0 application (client) that makes ajax/json calls to a http facade that then passes on the calls to our wcf service layer.
Users must authenticate on the client using forms authentication. The idea then being that the authentication cookie will be passed to and be accessible at the http facade. [Design based on Dino Esposito's book - Microsoft ASP.NET and AJAX: Architecting Web Applications]
The problem is, that at the facade, HttpContext.Current.User.Identity.Name is an empty string and IsAuthenticated is false.
I have enabled compatibility by adding the following to my system.ServiceModel section in my web.config (http facade level):
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
I have decorated my service with the following:
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Required)]
When I am debugging in the ajax/facade app I can see that cookies exist at HttpContext.Current.Request.Cookies. It appears that Anonymous is being used and not my authenticated user.
Both applications are running on the same IIS server.
Calls to the AJAX enabled wcf service are made via serviceProxy.js. Perhaps this method is not passing the necessary cookie?
WCF tracing is currently showing '..ASPXANONYMOUS=.....; ASP.NET_SessionId=....; .ASPXAUTH=.....' in the message log.
I get the feeling I am missing something simple but am too close to the problem.
Any suggestions welcomed.
I am not sure I completely understand the context of what you are trying to accomplish, but if these are two separate applications you are going to need to share machine keys in order to decrypt/encrypt the auth cookies in both.
in your web.config, make sure you have the following set:
<machineKey
validationKey="[generated key]"
validation="HMACSHA512"
decryptionKey="[generated key]"
decryption="AES"
/>
see how to generate these keys (and more info about them) on this codeproject article:
ASP.Net machineKey Generator - CodeProject
Let me know if this helps...
I'm using WCF service (via WebGet attribute).
I'm trying to access Session from WCF service, but HttpContext.Current is null
I added AspNetCompatibilityRequirements and edited web.config but I still cannot access session.
Is it possible to use WebGet and Session together?
Thank you!
Yes, it is possible. If you edit the web.config:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
and add the AspNetCompatiblityRequirements, the HttpContext.Current should be available.
Check everything once again, maybe you've put the attribute in the wrong place (the interface instead of the class?).
A RESTfull service with a session?
See excellent discussion here: Can you help me understand this? "Common REST Mistakes: Sessions are irrelevant"
http://javadialog.blogspot.co.uk/2009/06/common-rest-mistakes.html (point 6)
and
http://www.peej.co.uk/articles/no-sessions.html
Quote from Paul Prescod:
Sessions are irrelevant.
There should be no need for a client to "login" or "start a connection." HTTP authentication is done
automatically on every message. Client applications are consumers of
resources, not services. Therefore there is nothing to log in to!
Let's say that you are booking a flight on a REST web service. You
don't create a new "session" connection to the service. Rather you ask
the "itinerary creator object" to create you a new itinerary. You can
start filling in the blanks but then get some totally different
component elsewhere on the web to fill in some other blanks. There is
no session so there is no problem of migrating session state between
clients. There is also no issue of "session affinity" in the server
(though there are still load balancing issues to continue).
The app splits off into two threads; the main web app and a secondary thread used for asynchronous event handling. The secondary thread receives an event where it needs to send an email with a fully qualified URL of the main app (plus additional route arguments) inside it.
Eg. http://Server.com/App/RouteData?AdditionalArguments
Of course the background thread does not have the luxury of using HttpContext.Current to resolve a Url, because there's no request. No HttpRequest, no HttpContext...
I discovered that most of the methods ASP.NET (even with MVC) uses to build URLs rely on HttpContext. Does there exist a way to build a fully qualified application URL in ASP.NET without using HttpContext or any of it's derivatives?
I'm looking for a thread-safe method like:
UrlHelper.GetApplicationtUrl()
Any Ideas? Your suggestions are much appreciated.
I had this exact problem. I ended up storing the url in the web.config file. I did mine like so:
<appSettings>
<!-- Urls -->
<add key="AppDomain" value="http://localhost:1273/" />
<add key="ConfirmUrl" value="http://localhost:1273/Auth/Confirm/?code={0}" />
</appSettings>
and called it like this in the service layer:
string confirmUrl = string.Format(ConfigurationManager.AppSettings["ConfirmUrl"], confirmCode);
If you can't just use the configuration file, when creating the Thread, use the ThreadStart delegate to provide the base information you need to the new thread.