Request.QueryString not recognized, System.Web included in namespace - c#

A simple question but I'd rather ask since I had problem with it two times.
I am trying to retrieve hostname from the url in ASP.NET project. The code is actually not in a web page but in a class (part of the domain). System.Web is included in the headers. When I try to use Request.QueryString it is not recognized. Even worse if I try HttpContext.Current, I get this error
'System.Web.HttpContext.Current' is null
Here is my code
using System.Web;
public class MyNightlyJob : AbstractJob
{
public override void ExecuteJob(IJobExecutionContext context)
{
HttpContext.Current.Request.ServerVariables["HTTP_HOST"]; // does not work
Request.ServerVariables["HTTP_HOST"]; // this does not work also
}
}
What am I missing? Note that my question is actually about Request.ServerVariables but if one works, the other will work too.
Note that Request.ServerVariable is not recognized in the code at all. HttpContext.Current is recognized but I get run time error for that.

You need to check if HttpContext.Current is a null. If it is null then its not in the right context to be retrieved.
If you can modify the function, I would pass the HttpContext.Current as a variable or pass the host as a variable.

Related

Where is the dictionary key "MS_HttpContext" defined for HttpRequestMessage.Properties?

I've searched everywhere and nowhere does it mention where this key is defined, or similar ones such as HTTP_X_FORWARDED_FOR, REMOTE_ADDR etc.
MSDN documentation doesn't mention anything useful. The only thing close to useful I came about was some stackoverflow questions (this and this), along with this short blog post.
None of these sadly address my current question - from where does all these dictionary keys come from? Where is their specification, so that one knows they exist and learn to utilize them, by seeing the contents they hold?
EDIT: I'm using .NET Framework 4.6.0, where System.Net.Http's version is 4.0.0.0.
To get the client IP, I'm doing the following:
public string GetSomeIp(HttpRequestMessage request)
{
HttpContextWrapper context =
request.Properties["MS_HttpContext"] as HttpContextWrapper;
return (context == null) ?
string.Empty : (context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]
?? context.Request.ServerVariables["REMOTE_ADDR"]).Split(',')[0].Trim();
}
I'd like to find the documentation, which explains what MS_HttpContext does/holds in detail, as well as REMOTE_ADDR, HTTP_X_FORWADED_FOR, and where they are defined, so I can see all the other keys and more in detail of their implementation/proper usage.
I'm aware of the following server variables, but the keys used here are not mentioned there. (except REMOTE_ADDR)
I'd like to find the documentation, which explains what MS_HttpContext does/holds in detail
The System.Web.Http.* assemblies seem not described on the https://referencesource.microsoft.com/.
However, all these projects are now hosted on the GitHub as Open? Source https://github.com/aspnet/AspNetWebStack.
So far, I assume that this constant/key is used within a routine that assigns the System.Web -> HttpContext to System.Web.Http -> Request.
https://github.com/aspnet/AspNetWebStack/blob/master/src/System.Web.Http.WebHost/HttpRequestMessageExtensions.cs#L11-L44
Another occurrences are related to CORS and Tests. You can clone this repo and search for the "MS_HttpContext" occurrences in depth in you are looking for details. However, I am not sure about its documentation.
where this key is defined, or similar ones such as HTTP_X_FORWARDED_FOR, REMOTE_ADDR etc.
from where does all these dictionary keys come from?
These request's properties (aka Server Variables) are created (almost duplicated) from the corresponding headers sent by a client here (applicable for HttpContext - ASP.NET WebForms/MVC):
https://referencesource.microsoft.com/#System.Web/HttpRequest.cs,dc76880a3cfd0009
https://referencesource.microsoft.com/#System.Web/HttpRequest.cs,639
By the way, there are no more such properties in the HttpRequest for ASP.NET Core (headers only).
If you need to grab the client IP information, use any approach from the aforementioned (yours or suggested) links.
If you need to retrieve the familiar HttpContext instance (for example, outside the ApiController, for example, DelegatingHandler/aka middleware), use any of the approaches illustrated in this (already mentioned as well).
If you need to retrieve it inside the ApiController, it may be even easier (don't forget about required null ref checks and self-hosted WebAPI solutions):
public class YourApiController : ApiController {
public HttpResponseMessage YourActionName() {
var request = new HttpContextWrapper(CurrentContext).Request;
...
}
}
public class YourAuditHandler : DelegatingHandler {
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
string ipAddress = HttpContext.Current != null ? HttpContext.Current.Request.UserHostAddress : "0.0.0.0";
...
}
}

a proxy type with the name account has been defined by another assembly

We have 2 orgs running in our on-premise crm 2011 system.
We have generated early bound classes for both orgs.
One of our plugins is throwing the "a proxy type with the name account has been defined by another assembly" error when deactivating an account.
That plugin only references one of the early bound dll's.
How do I get the CRM system to respect the namespace of these references.
I've tried the few items that show up from Google and none are working.
Since you can reproduce this with 2 vanilla orgs I would imaging there is something OUTSIDE the code layer we can do without having to go back and refactor a bunch of code for the 2 orgs.
Thanks,
Jon
The problem is actually with WCF attempting to deserialize the server response and not being able to identify the correct type. The best method to sort this issue is to pass in the current assembly using Assembly.GetExecutingAssembly() to the ProxyTypesBehavior() while creating the proxy like so.
using (serviceProxy = new OrganizationServiceProxy(config.OrganizationUri,
config.HomeRealmUri,
config.Credentials,
config.DeviceCredentials))
{
// This statement is required to enable early-bound type support.
serviceProxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior(Assembly.GetExecutingAssembly()));
}
You may run into this issue when referencing different assemblies containing proxy-classes, i.e. one assembly wrapping the server SDK (Microsoft.Xrm.Sdk) and another assembly wrapping the client SDK (Microsoft.Xrm.Sdk.Client).
In such a scenario it seems to be required to tell the OrganizationServiceProxy which assembly should be used to resolve the proxy classes.
This should help:
var credentials = new ClientCredentials();
credentials.Windows.ClientCredential = new System.Net.NetworkCredential(userName, password, domain);
var proxy = new OrganizationServiceProxy(new Uri(discoveryUrl), null, credentials, null);
proxy.EnableProxyTypes(typeof(CrmServiceContext).Assembly);
var context = CrmServiceContext(proxy);
The important thing is to call EnableProxyTypes by passing the correct assembly. I saw another solution using CrmConnection but CrmConnection is only available in the client SDK, which means that you can't instantiate a "server-OrganizationServiceProxy" this way. EnableProxyTypes(Assembly assembly) works for both sides.
Hope this helps.
Regards,
MH
It maybe years since this question has been raised. However, I faced this problem recently and have been extremely worried about thousands of lines of code to be changed. However, I was lucky to find the following simple change to get myself out of hell:
Suppose there are two context objects you deal with:
an OrganizationServiceContext object: context1
a CrmSvcUtil Context object: context2
and a single OrganizationServiceProxy object: service
if in a single method, you make multiple CRUD operations using the same service object but with either of context objects as exemplified above, it is highly probable that this error be raised. However, by doing the following, you can prevent it to happen.
Every time you want to work with context1, you precede the context object with the service object as following:
service.EnableProxyTypes(typeof(OrganizationServiceContext).Assembly);
using (var context1 = new OrganizationServiceContext(_service)){
// your classic code here
}
Also, every time you want to work with context2, you follow the same structure:
service.EnableProxyTypes(typeof(HiwebContext).Assembly);
using (var context = new XYZContext(this._service)){
// your CrmSvcUtil none-classic code here
}
this normally means that there is one or more assemblies with the same method name or property to fix this use the fully qualified name of the assembly.. for example in the using System.IO for example if you had a method named the same way in your Class code that conflicts with System.IO.... you would write your fix like
thisObject.System.IO.Path( ---- ) = somthing for example.. does this make sense..?
I found that adding the Assembly.GetExecutingAssembly() solved the problem.
adding the Assembly.GetExecutingAssembly() solve my problem, you also need to add using System.Reflection;
thanks

Session State variables aren't working

I'm writing an ASP.NET C# web site that needs to access data from a database and show it to the user for viewing and editing. The specific data it accesses is based on the user who logs in, and I need for multiple users to be able to use the site simultaneously, viewing and editing different data as they do so. I stumbled upon the concept of Session States, and after a lot of reading and not as much understanding. I've come across a problem.
In my default page, I do this to create a Session variable:
Session.Add("UserData",userdata);
I have also tried this:
Session["UserData"] = userdata;
Then in a later page, I do this to try to call it:
object myobject = Session["UserData"];
This gives me an error, saying that Session["UserData"] is not set to an instance of an object. This is the method everyone seems to be using, is there something I'm missing?
My site is configured on IIS to have the Session State Mode set to "In Process", but most people seem to set this manually using their web.config file. However, when I try to do this in my web.config file I am always greeted with "unrecognized configuration section". My compiler doesn't know what this is:
<sessionstate mode="inproc"/>
EDIT, more detailed code:
MyClass userdata = new MyClass();
userdata.name = "myname";
userdata.number = 5;
Session["UserData"] = userdata;
later...
MyClass mydata = (MyClass)(Session["UserData"]);
This returns the error that Session["UserData"] is null.
The fact that you can't set the session mode in the web.config is a red flag to me of something weird and smelly going on. So ...
Check that the session mode is under the system.web element of the web.config otherwise it won't be valid.
Check that enableSessionState hasn't been set to false in either the web.config or the page directive
Try to rule out IIS. If possible convert your website to a web app and run through visual studio so it starts with it's own built in web server. What happens then? Is the Session state back?
It should n't make a difference but if you are not doing the test in Page_Load then just try it there - just in case you are doing these tests somewhere unusual.
Whatever the answer is to this when we know it will be headachingly obvious. I'm geninuely looking forward to finding out what it is. Good luck
Session variables are good to manage multiple users on your website, but to initialize them you should use the Global.asax file in your web application. This file has two methods specifically for Session variables, Session_Start and Session_End. To initialize your Session variable you would use code liked the following in Global.asax:
void Session_Start(object sender, EventArgs e)
{
// initialize session variable
Session["MySessionVar"] = 1;
}
Also you may have to cast the value of your session variable if you are doing operations on it like +, for example if you have a session variable holding an integer value, you may have to do like the following:
Session["MySessionVar"] = ((int) Session["MySessionVar]) + 1;
Also, if you try to use your session variable outside of a method like Page_Load or other method, like trying to use it as a property of the System.Web.UI.Page class in your C# code behind file, that may not work, you can only use your session variables within a method.
I would search for any calls to Session.Clear or Session.Abandon to see if your session is being purged in between those two actions.
You could also hook up to the Session_End event and see if that gets hit sometime in between the two calls.
Where you have
Session.Add("UserData",userdata);
you want to check the value you need to cast the object with (string) like this
string userdata= (string)(Session["UserData"]);
you could then run a check to see
if(string.IsNullOrEmpty(userdata))
but not sure how you are initializing and assigning a a value to userdata
Does it complain the your myobject is null or that Session is null? When you try to retrieve the value you are doing this from the method of what class?
Yet another question - by any chance are you trying to access it in a parallel thread?

Does static reference to HttpContext.Current.Session return same session for all users?

Is there room for issue in the following code in terms of multiple users of the same web application? I mean, I know that a purely static string will be shared across all sessions for a single ASP.NET application, but given that this explicitly refers to the Current.Session, even though it is static it seems like it would always refer to the session instance of the "current user."
But an error is happening that could be explained by everyone sharing the current value of Mode and thus the most recent change overwriting everyone else's mode value.
(As a background: This string is in a Helpers class that is used throughout the application. I do not want to make hard-coded references to Session["Mode"] throughout the application and do not want to have to pass Session["Mode"] in every method call from an aspx.cs page.)
public static string Mode
{
get
{
var value = HttpContext.Current.Session["Mode"];
return (value ?? string.Empty).ToString();
}
set
{
HttpContext.Current.Session["Mode"] = value;
}
}
HttpContext.Current always returns the context of the current request (if there is a current request).
Since each user will be executing a different request, each context will be different.
Your property is static. This is actually the cause of sharing the property between users.
See Scope of static Variable in multi-user ASP.NET web application for more details.

How can I get the URL of the current page from within a C# App_Code class?

I have a logging class that, well, logs things. I would like to add the ability to automatically have the current page be logged with the messages.
Is there a way to get the information I'm looking for?
Thanks,
From your class you can use the HttpContext.Current property (in System.Web.dll). From there, you can create a chain of properties:
Request
Url and RawUrl
The underlying object is a Page object, so if you cast it to that, then use any object you would normally use from within a Page object, such as the Request property.
It's brittle and hard to test but you can use System.Web.HttpContext.Current which will give you a Request property which in turn has the RawUrl property.
public static class MyClass
{
public static string GetURL()
{
HttpRequest request = HttpContext.Current.Request;
string url = request.Url.ToString();
return url;
}
}
I tried to break it down a little :)
In the past I've also rolled my own logging classes and used Console.Writeln() but really there are a number of good logging options that already exist so why go there? I use NLog pretty much everywhere; it is extremely flexible with various log output destinations including console and file, lots of log format options, and is trivial to set up with versions targeting the various .net frameworks including compact. Running the installer will add NLog config file options to the Visual Studio Add New Item dialog. Using in your code is simple:
// declare in your class
private static Logger logger = LogManager.GetCurrentClassLogger();
...
// use in your code
logger.Debug(() => string.Format("Url: {0}", HttpContext.Current.Request.Url));

Categories