I have a webservice 'mywebservice' and a web method 'mywebmethod' defined in it.
This web method calls a function 'callme()' which is defined in another class.
I want to get the service name which is calling this function and also the methodname. I want this in 'callme()' function.
--'mywebservice.asmx.cs'
[WebMethod]
public void mywebmethod
{
callme();
}
-- 'class1.cs'
public void callme()
{
// --- I want service name(mywebservice) & methodname(mywebmethod) here.
}
One possible way could be to use StackTrace class (see example section to get started) to walk back to call stack to get type name & method name - this will give you the names for class/method implementing the service.
Mind you that stack trace construction is an expensive operation - as such, I would recommend to pass necessary information as parameters to the method. Further, if you could state why you need this information (service & method name), you may get an better answer to solve your actual problem.
Related
I'm trying to get an understanding of which concrete types are providing the implementations of interfaces in an IOC (dependency injection) container. My implementation works fine when there are no delegates involved. However, I'm having trouble when a delegate method is passed as the type factory, as I can't get Mono.Cecil to give me the concrete type or a method reference to the factory back. I'm specifically in this case trying to build a component that can work with the IServiceCollection container for .Net ASP.Net REST APIs. I've created a 'minimised' set of code below to make it easy to explain the problem.
Consider the following C# code:
interface IServiceProvider {}
interface IServiceCollection {}
class ServicesCollection : IServiceCollection {}
interface IMongoDBContext {}
class MongoDBContext : IMongoDBContext
{
public MongoDBContext(string configName) {}
}
static class Extensions
{
public static IServiceCollection AddSingleton<TService>(this IServiceCollection services, Func<IServiceProvider, TService> implementationFactory) where TService : class
{
return null;
}
}
class Foo
{
void Bar()
{
IServiceCollection services = new ServicesCollection();
services.AddSingleton<IMongoDBContext>(s => new MongoDBContext("mongodbConfig"));
}
}
When successfully locating the 'services.AddSingleton' as a MethodReference, I'm unable to see any reference to the MongoDBContext class, or its constructor. When printing all the instructions .ToString() I also cannot seem to see anything in the IL - I do see the numbered parameter as !!0, but that doesn't help if I can't resolve it to a type or to the factory method.
Does anyone have any ideas on how to solve this?
Most likely your code is looking in the wrong place.
C# compiler will try to cache the conversion of lambda expression -> delegate.
if you look in sharplab.io you'll see that the compiler is emitting an inner class '<>c' inside your Foo class and in that class it emits the method '<Bar>b__0_0' that will be passed as the delegate (see opcode ldftn).
I don't think there's an easy, non fragile way to find that method.
That said, one option would be to:
Find the AddSingleton() method call
From there start going back to the previous instructions trying to identify which one is pushing the value consumed in 1 (the safest way to do that would be to consider how each instruction you are visiting changes the stack). In the code I've linked, it would be IL_0021 (a dup) of Bar() method.
From there, do something similar to 2, but now looking for the instruction that pushes the method reference (a ldftn) used by the ctor of Func<T, R>; in the code linked, it would be IL_0016.
Now you can inspect the body (in the code linked, Foo/'<>c'::'<Bar>b__0_0')
Note that this implementation has some holes though; for instance, if you call AddSingleton() with a variable/parameter/field as I've done (services.AddSingleton(_func);) you'll need to chase the initialization of that to find the referenced method.
Interestingly, at some point Cecil project did support flow analysis (https://github.com/mono/cecil-old/tree/master/flowanalysis).
If you have access to the source code, I think it would be easier to use Roslyn to analyze it (instead of analyzing the assembly).
I use SpringBoot for REST web services development and SonarQube for static analysis.
I have a few endpoints in my application that look the following way:
#PostMapping
ResponseEntity<?> addSomething(#RequestBody Some object) {
// some code there
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
SonarQube complains about using ResponseEntity with a wildcard, reporting me a Critical issue "Generic wildcard types should not be used in return parameters".
I wonder if I should disable this verification in SonarQube or come up with something different for return type for these cases.
What do you think about it?
#PostMapping
ResponseEntity<Object> addSomething(#RequestBody Some object) {
// some code there
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
This will also remove the error. It is still very generic, but it is one of the solutions if you want to return different types based on the outcome. For instance:
#PostMapping
ResponseEntity<Object> addSomething(#RequestBody Some object) {
//Will return ResponseEntity<> with errors
ResponseEntity<Object> errors = mapValidationService(bindingResult);
if (!ObjectUtils.isEmpty(errors)) return errors;
// some code there
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
So actually i find the rule pretty self describing:
Using a wildcard as a return type implicitly means that the return value should be considered read-only, but without any way to enforce this contract.
Let's take the example of method returning a "List". Is it possible on this list to add a Dog, a Cat, ... we simply don't know. The consumer of a method should not have to deal with such disruptive questions.
https://sonarcloud.io/organizations/default/rules#rule_key=squid%3AS1452
So Actually in your case, you do not want any kind of Class in there, you specifically want an Serializable-object - for obvious reasons: it should be serialized later on
So instead of using ? it would be more suitable in your case to use Serializable. This is always case dependent, but normally you definitly expect some kind of common interface or base class as a return value. Hence that, the follow up developer, definitly knows what he can expect, and what kind of functionality he definitly can use.
Finally I've removed <?> from return value, so the code looks like the following now:
#PostMapping
ResponseEntity addSomething(#RequestBody Some object) {
// some code there
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
SonarQube doesn't complain anymore and code seems a little bit simpler now.
I'm writing in C# for ASP.NET Web API 2. What I want is a catch-all method that will execute for every single request that comes to my Web API.
If the method returns null, then the original routing should continue, seeking out the correct method. However, if the method returns, say, an HTTPResponseMessage, the server should return that response and not proceed on to normal routing.
The use case would be the ability to handle various scenarios that may impact the entire API. For example: ban a single IP address, block (or whitelist) certain user agents, deal with API call counting (e.g. someone can only make X requests to any API method in Y minutes).
The only way I can imagine to do this right now is to literally include a method call in each and every new method I write for my API. For example,
[HttpGet]
public HttpResponseMessage myNewMethod()
{
// I want to avoid having to do this in every single method.
var check = methodThatEitherReturnsResponseOrNull(Request);
if (check != null) return (HttpResponseMessage)check;
// The method returned null so we go ahead with normal processing.
...
}
Is there some way to accomplish this in routing?
This is what Action Filters are for. These are Attributes that you can place either globally, at the class (Controller), or at the method (Action) levels. These attributes can do preprocessing where you execute some code before your action executes or post processing where you execute code after the action executes.
When using pre processing you have the option to return a result to the caller and not have your method (action) be fired at all. This is good for model validation, authorization checks, etc.
To register a filter globally edit the WebApiConfig.cs file.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new YourFilterAttribute()); // add record
// rest of code
}
}
To create a custom attribute inherit from System.Web.Http.Filters.ActionFilterAttribute or you can implement interface System.Web.Http.Filters.IActionFilter or you can implement IAuthorizationFilter/AuthorizationFilterAttribute if you specifically want to allow/deny a request.
It also sounds like you want to create multiple attributes, one for each role like IP filtering or count calling etc. That way it would be more modular instead of one enormous authorization filter.
There are many tutorials out there like this one (chosen at random in my Google search results). I am not going to post code because you did not do so either so I would just be guessing as to what you wanted to do.
Disclaimer: I am a complete biztalk newbie.
I need to be able to read and potentially edit 4 nodes in a biztalk message; preferably this needs to be done from a c# helper class as I am making a service call and also have unit tests written for this.
I already have this class wired up and it works with the XLANGMessage class, the problem I am running into is at this point in the orchestration the message is a Schema based type and doesn't seem to have any way for me to modify it.
I've done some reading and found a few ideas but have not been able to confirm if any of these can work from custom code.
1 write a map to transform the incoming message to the desired type
or
2 write something like this in your helper component to transform the message
public XmlDocument TransformMessage(XLANGMessage message)
Then pass the result document to a biztalk message in a message assignment shape.
responseMessage = xmlDocument;
You may get better performance if you pass streams instead of messages around.
You can pass messages into and out of C# helper classes easily. The simplest way is just to treat input parameters and return values as of type System.Xml.XmlDocument. The XLANG/s engine will safely cast back and forth from the XLANGMessage type to XmlDocument.
As you are essentially creating a "new" instance of the message (messages are immutable in BizTalk), the call to your helper class needs to be performed in a Message Assignment shape, with the outer Construct shape constructing the copy of your original message.
public static XmlDocument UpdateMyMessage(XmlDocument sourceMessage)
{
/* Do stuff to your Message here */
return sourceMessage;
}
A best-practice to consider is to declare all your C# helper methods as Static. This will avoid any issues with de/serialisation of your helper class during dehydration.
Are BizTalk messages immutable?
Generally speaking they are however, by creating a “corrective” orchestration and using a pass by reference option on the incoming message parameter, an existing message can be modified.
I have a web service (an ASP.NET .asmx page), and for debugging purposes I need to log all calls to the webservice, including values of all parameters passed into each call. So basically the first thing each WebMethod should do is log it's state with details of all the parameter values passed in to it.
So far so good. The complication is that I also want an automated way of getting the parameter values - there's quite a few webmethods with different signatures, and some of them have up to ~30 parameters, so manually coding against each specific parameter would likely be massively error-prone. I'd rather be able to call a method that looks at the current Http context and automatically uses that to grab and parse whatever has been passed in by the client.
But I hit a snag. When I look at HttpContext.Current.Request, it turns out that both the Form and QueryString collections are empty. So if the arguments passed to the webmethod aren't in either of those collections, where would they be? Anyone know how I can retrieve them?
You can use AOP techniques for this task. Considering PostSharp, you can create custom aspect like this:
[Serializable]
public class TraceAttribute : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
Trace.WriteLine(string.Format("Entering {0}", args.Method.Name));
for (int i = 0; i < args.Arguments.Count; i++)
{
Trace.WriteLine(string.Format(" {0}", args.Arguments.GetArgument(i)));
}
}
}
and then apply it to your web-service methods:
[WebMethod, Trace]
public string HelloWorld()
{
return "Hello World";
}
You could use SOAP extensions and follow the example in this post to log the request which would have the method name and parameters.
SOAP Extentions is a better choice. Here is another example to retreive SOAP request and SOAP response as XML. All you do is parse the XML to retreive parameter name value pairs.