ASP.NET MVC - Session is null - asp.net

I have an MVC3 application on .net4 that its session working in the dev Environment, but not in the production.
In the production I logged the sessionID and the it is the same in the moment I Set and Get from the session.
When I try to get the session I am getting Null Exception.
This is how I access the session:
public static class HandlersHttpStorage
{
public static string TestSession
{
get
{
return HttpContext.Current.Session["time"];//This is null
}
set
{
HttpContext.Current.Session.Add("time", value);//DateTime.Now.ToString()
}
}
}
What's makes me worried is that the behavior in the production is different than the development, even though the web.config is the same.

Solution 1:
Link: HttpContext.Current.Session is null when routing requests
Got it. Quite stupid, actually. It worked after I removed & added the SessionStateModule like so:
<configuration>
...
<system.webServer>
...
<modules>
<remove name="Session" />
<add name="Session" type="System.Web.SessionState.SessionStateModule"/>
...
</modules>
</system.webServer>
</configuration>
Simply adding it won't work since "Session" should have already been defined in the machine.config.
Now, I wonder if that is the usual thing to do. It surely doesn't seem so since it seems so crude...
Solution 2:
Link: HttpContext.Current.Session null item
sessionKey may be changing, you probably only need to do:
HttpContext.Current.Session["CurrentUser"]
Or the session may be expiring, check the timeout:
http://msdn.microsoft.com/en-us/library/h6bb9cz9(VS.71).aspx
Or you may be setting the session value from somewhere else, normally i control access to Session/Context object through one property
static readonly string SESSION_CurrentUser = "CurrentUser";
public static SiteUser Create() {
SiteUser.Current = new SiteUser();
return SiteUser.Current;
}
public static SiteUser Current {
get {
if (HttpContext.Current.Session == null || HttpContext.Current.Session[SESSION_CurrentUser] == null) {
throw new SiteUserAutorizationExeption();
}
return HttpContext.Current.Session[SESSION_CurrentUser] as SiteUser;
}
set {
if (!HttpContext.Current.Session == null) {
HttpContext.Current.Session[SESSION_CurrentUser] = value;
}
}
}

Another possible cause/solution is that IE doesn't save cookies if the domain name has an underscore (because strictly speaking domain names can't have underscores, so you'll probably only encounter this in development), e.g. http://my_dev_server/DoesntWork. Chrome or Firefox should work in this scenario, and if you change the domain name you're using to not have an underscore problem solved.
Ref:
http://blog.smartbear.com/software-quality/internet-explorer-eats-cookies-with-underscores-in-the-hostname/
http://social.msdn.microsoft.com/Forums/ie/en-US/8e876e9e-b223-4f84-a5d1-1eda2c2bbdf4/ie7-cookie-issue-when-domain-name-has-underscore-character-in-it?forum=iewebdevelopment

For me, I found that HttpContext.Current was null, so I created it:
System.Web.HttpContext c = System.Web.HttpContext.Current;
And I passed that into my function that was in my other class, like this:
string myString = "Something to save";
SessionExtensions.SetDataToSession<string>(c, "MyKey1", myString);
I had actually wanted my function to be a real extension method off of Session like the one below, but what I found was this HttpSessionStateBase session was null, it would give the NullReferenceException when I tried to add anything to Session using it. So this:
public static class SessionExtensions
{
/// <summary>
/// Get value.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="session"></param>
/// <param name="key"></param>
/// <returns></returns>
public static T GetDataFromSession<T>(this HttpSessionStateBase session, string key)
{
return (T)session[key];
}
/// <summary>
/// Set value.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="session"></param>
/// <param name="key"></param>
/// <param name="value"></param>
public static void SetDataToSession<T>(this HttpSessionStateBase session, string key, object value)
{
session[key] = value;
}
}
That Microsoft had here: https://code.msdn.microsoft.com/How-to-create-and-access-447ada98 became this, instead:
public static class SessionExtensions
{
/// <summary>
/// Get value.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="session"></param>
/// <param name="key"></param>
/// <returns></returns>
public static T GetDataFromSession<T>(HttpContext context, string key)
{
if (context != null && context.Session != null)
{
context.Session.Abandon();
}
return (T)context.Session[key];
}
/// <summary>
/// Set value.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="session"></param>
/// <param name="key"></param>
/// <param name="value"></param>
public static void SetDataToSession<T>(HttpContext context, string key, object value)
{
context.Session[key] = value;
}
}
And I was able to retrieve my data like this:
System.Web.HttpContext c = System.Web.HttpContext.Current;
string myString = SessionExtensions.GetDataFromSession<string>(c, "MyKey1");
And, of course, since HttpContext.Current and Session now exists, I was able to even simplify that to be:
string myString = Session["MyKey1"].ToString();
If this had been object, you would put the object's type in place of <string> in the SetDataToSession()
function:
List<string> myStringList = new List<string>();
myStringList.Add("Something to save");
SessionExtensions.SetDataToSession<List<string>>(c, "MyKey1", myStringList);
And to retrieve it:
System.Web.HttpContext c = System.Web.HttpContext.Current;
List<string> myStringList = SessionExtensions.GetDataFromSession<List<string>>(c, "MyKey1");
or simply:
List<string> myStringList = (List<string>)Session["MyKey1"];

Related

Can there be multiple instances of a dependency in Xamarin.Forms?

I have mirrored some code from XLabs to get Network State Tracking on my device from here: Xlabs INetwork Android Implementation
I've pretty much aligned it with coding standards here and changed some method names - everything is working fine, except for some reason on the android implementation i am unable to get my event handlers to respond, the same way they do on iOS.
This is my Adaptation for Android:
[assembly: Dependency(typeof(STM.Droid.DependencyInjection.Network))]
[assembly: UsesPermission("android.permission.ACCESS_NETWORK_STATE")]
[assembly: UsesPermission("android.permission.ACCESS_WIFI_STATE")]
[assembly: UsesPermission("android.permission.CHANGE_NETWORK_STATE")]
[assembly: UsesPermission("android.permission.CHANGE_WIFI_STATE")]
namespace Namespace.Droid
{
[BroadcastReceiver(Enabled = true)]
[IntentFilter(new [] { Android.Net.ConnectivityManager.ConnectivityAction })]
public class Network : BroadcastReceiver, INetwork
{
/// <summary>
/// Internets the connection status.
/// </summary>
/// <returns>NetworkStatus.</returns>
public NetworkStatus GetConnectionStatus()
{
var status = NetworkStatus.NotReachable;
using (var cm = (ConnectivityManager)Application.Context.GetSystemService(Context.ConnectivityService))
using (var ni = cm.ActiveNetworkInfo)
{
if (ni != null && ni.IsConnectedOrConnecting)
{
var name = ni.TypeName.ToUpper();
if (name.Contains("WIFI"))
{
status = NetworkStatus.ReachableViaWiFiNetwork;
}
else if (name.Contains("MOBILE"))
{
status = NetworkStatus.ReachableViaCarrierDataNetwork;
}
else
{
status = NetworkStatus.ReachableViaUnknownNetwork;
}
}
}
return status;
}
private readonly object lockObject = new object();
private EventHandler<NetworkStatus> _reachabilityChanged;
public event EventHandler<NetworkStatus> ReachabilityChanged
{
add
{
lock (this.lockObject)
{
this._reachabilityChanged += value;
}
}
remove
{
lock (this.lockObject)
{
this._reachabilityChanged -= value;
}
}
}
/// <summary>
/// Occurs when [reachability changed].
/// </summary>
// public event EventHandler<NetworkStatus> ReachabilityChanged;
/// <summary>
/// Determines whether the specified host is reachable.
/// </summary>
/// <param name="host">The host.</param>
/// <param name="timeout">The timeout.</param>
public Task<bool> IsReachableAsync(string host, TimeSpan timeout)
{
return Task.Run(
() =>
{
try
{
var address = InetAddress.GetByName(host);
return address != null; // && (address.IsReachable((int)timeout.TotalMilliseconds) || );
}
catch (UnknownHostException)
{
return false;
}
});
}
/// <summary>
/// Determines whether [is reachable by wifi] [the specified host].
/// </summary>
/// <param name="host">The host.</param>
/// <param name="timeout">The timeout.</param>
public async Task<bool> IsReachableByWifiAsync(string host, TimeSpan timeout)
{
return GetConnectionStatus() == NetworkStatus.ReachableViaWiFiNetwork && await IsReachableAsync(host, timeout);
}
/// <summary>
/// This gets called by OS when the <see cref="ConnectivityManager.ConnectivityAction"/> <see cref="Intent"/> fires.
/// </summary>
/// <param name="context">Context for the intent.</param>
/// <param name="intent">Intent information.</param>
public override void OnReceive(Context context, Intent intent)
{
// this is a workaround - which oddly enough forwards events the way i would expect it to.
MessagingCenter.Send(this as INetwork, string.Empty, GetConnectionStatus());
// THIS IS ALWAYS NULL!
var handler = _reachabilityChanged;
if (handler != null)
{
var connectionStatus = this.GetConnectionStatus();
handler(this, connectionStatus);
}
}
}
}
The error in question occurs in OnReceive.
While in debugging i do notice that the handlers are attached correctly on the PCL side - there will just be null on that _reachabilityChanged field oddly enough.
As debugging indicates i am apparently getting
{md50e2cce2f1202796e628729fe0540389b.Network#b422684}
on the droid OnReceive method for "this"
while on the PCL side i am getting
{md50e2cce2f1202796e628729fe0540389b.Network#b562641}
when calling DependencyService.Get
To me this looks like the reason the handler list is empty, is because i am subscribing my handler on another instance and therefore do not get any handlers when a different instance of Network calls OnReceive.
Is it even possible for Xamarin.Forms DependencyService to provide 2 or more instances of an instance? Because that would surprise me a lot...
UPDATE:
In case someone needs a workaround - this works as well:
public event EventHandler<NetworkStatus> ReachabilityChanged
{
add { MessagingCenter.Subscribe(value.Target, string.Empty, (INetwork d, NetworkStatus a) => value(d, a)); }
remove { MessagingCenter.Unsubscribe<INetwork>(value.Target, string.Empty); }
}
for new instance
_client = DependencyService.Get<YOUINTERFACE>(DependencyFetchTarget.NewInstance);
by default DependencyService is keep single

[OpenStack .NET API]: Is there a way to combine the Object creation and Container creation in one call?

Currently I do this
try
{
cloudFilesProvider.CreateObjectFromFile(inStrContainerName, inStrSrcFilePath, strDesFileName, 4096, FileMetaData);
}
catch (ItemNotFoundException ex1)
{
try
{
cloudFilesProvider.CreateContainer(inStrContainerName);
cloudFilesProvider.CreateObjectFromFile(inStrContainerName, inStrSrcFilePath, strDesFileName, 4096, FileMetaData);
}
catch(Exception ex2)
{
return false;
}
}
So essentially if the container does not exist then its 3 separate API calls.
Is there a more efficient way to do this?
You can simplify the code by reducing it to the following two lines.
cloudFilesProvider.CreateContainer(inStrContainerName);
cloudFilesProvider.CreateObjectFromFile(inStrContainerName, inStrSrcFilePath, strDesFileName, 4096, FileMetaData);
CreateContainer is safe to call for a container that already exists. It returns ContainerCreated if the container is created, or ContainerExists if the container was not created because it already exists.
PS: The return values (with information like the above) for the IObjectStorageProvider methods will be well documented for release 1.2.0.0.
Edit: To reduce the number of API calls your code makes, you could use a cache class like the following. The CreateIfNecessary method attempts to create the container only if it is not previously known to exist. The ClearCache method provides a manual method for continuing to use the cache even if you delete a container.
This code is currently untested.
public class ContainerManager
{
private readonly CloudFilesProvider _provider;
private readonly string _region;
private readonly bool _useInternalUrl;
private readonly CloudIdentity _identity;
private readonly HashSet<string> _containers = new HashSet<string>();
public ContainerManager(CloudFilesProvider provider, string region, bool useInternalUrl, CloudIdentity identity)
{
if (provider == null)
throw new ArgumentNullException("provider");
_provider = provider;
_region = region;
_useInternalUrl = useInternalUrl;
_identity = identity;
}
/// <summary>
/// Clears the cache of known containers.
/// </summary>
/// <remarks>
/// <alert class="warning">
/// If a container was deleted after this cache was in use, this method must be called or
/// <see cref="CreateIfNecessary(string)"/> could fail to create a container which does not
/// exist.
/// </alert>
/// </remarks>
public void ClearCache()
{
lock (_containers)
{
_containers.Clear();
}
}
/// <summary>
/// Ensures that a container exists in the Cloud Files store.
/// </summary>
/// <remarks>
/// <alert class="warning">
/// If a container was deleted after this cache was in use, and <see cref="ClearCache()"/>
/// has not been called, this method could fail to create a container which does not exist.
/// </alert>
/// </remarks>
/// <param name="container">The name of the container to create.</param>
/// <exception cref="ArgumentNullException">If <paramref name="container"/> is <c>null</c>.</exception>
/// <exception cref="ArgumentException">If <paramref name="container"/> is empty.</exception>
/// <returns><c>true</c> if the container was created; otherwise <c>false</c> if the container already existed.</returns>
public bool CreateIfNecessary(string container)
{
if (container == null)
throw new ArgumentNullException("container");
if (string.IsNullOrEmpty(container))
throw new ArgumentException("container cannot be empty");
// don't try to create the same container multiple times
if (_containers.Contains(container))
return false;
ObjectStore result = _provider.CreateContainer(container, _region, _useInternalUrl, _identity);
if (result == ObjectStore.ContainerCreated || result == ObjectStore.ContainerExists)
{
lock (_containers)
{
// add to _containers even if the result is ContainerExists, because that
// means it simply wasn't known to this cache.
_containers.Add(container);
}
}
// only return true if the container was actually created
return result == ObjectStore.ContainerCreated;
}
}

Revalidate Model When Using WebAPI (TryValidateModel equivalent)

Using vanilla MVC I can revalidate my model with TryValidateModel. The TryValidateModel method doesn't seem to be applicable to WebAPI. How can I revalidate my model when using WebAPI?
I know it has been a while since this has been asked, but the problem is still valid. Thus i thought i should share my solution to this problem.
I decided to implement the TryValidateModel(object model) myself, based on the implementation in the System.Web.Mvc.Controller.cs
The problem is that the mvc's TryValidateModel internally used their own HttpContext and ModelState. If you go and compaire the two, they are very similar....
The be able to use our own HttpContext there exists a HttpContextWrapper that can be used for that.
And Since we have to clear our model state, it doesn't really matter that we use a different type of ModelState , as long as we get the desired result, thus i create a new ModelState object from the correct type...
I did add the error to the ModelState of the controller and not to the model state to the newly created ModelState , This seems to work just fine for me :)
Here is my code, that i just added to the controller...
do not forget to import the library...
using System.Web.ModelBinding;
protected internal bool TryValidateModel(object model)
{
return TryValidateModel(model, null /* prefix */);
}
protected internal bool TryValidateModel(object model, string prefix)
{
if (model == null)
{
throw new ArgumentNullException("model");
}
ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, model.GetType());
var t = new ModelBindingExecutionContext(new HttpContextWrapper(HttpContext.Current), new System.Web.ModelBinding.ModelStateDictionary());
foreach (ModelValidationResult validationResult in ModelValidator.GetModelValidator(metadata, t).Validate(null))
{
ModelState.AddModelError(validationResult.MemberName, validationResult.Message);
}
return ModelState.IsValid;
}
I don't know when was it added but now there is Validate method on api controller.
ApiController.Validate Method (TEntity)
https://msdn.microsoft.com/en-us/library/dn573258%28v=vs.118%29.aspx
Based from rik-vanmechelen original answer, here is my version that relies on the services container exposed by Web API.
/// <summary>
/// Tries to validate the model.
/// </summary>
/// <param name="model">The model.</param>
/// <returns>Whether the model is valid or not.</returns>
protected internal bool TryValidateModel(object model)
{
if (model == null)
{
throw new ArgumentNullException("model");
}
var metadataProvider = Configuration.Services.GetService<System.Web.Http.Metadata.ModelMetadataProvider>();
var validatorProviders = Configuration.Services.GetServices<System.Web.Http.Validation.ModelValidatorProvider>();
var metadata = metadataProvider.GetMetadataForType(() => model, model.GetType());
ModelState.Clear();
var modelValidators = metadata.GetValidators(validatorProviders);
foreach (var validationResult in modelValidators.SelectMany(v => v.Validate(metadata, null)))
{
ModelState.AddModelError(validationResult.MemberName, validationResult.Message);
}
return ModelState.IsValid;
}
This uses the following simple extension methods to access the services :
/// <summary>
/// Services container extension methods.
/// </summary>
public static class ServicesContainerExtensions
{
/// <summary>
/// Gets the service.
/// </summary>
/// <typeparam name="TService">The type of the service.</typeparam>
/// <param name="services">The services.</param>
/// <returns>The service.</returns>
/// <exception cref="System.ArgumentNullException">services</exception>
public static TService GetService<TService>(this ServicesContainer services)
{
if (services == null)
{
throw new ArgumentNullException("services");
}
return (TService)((object)services.GetService(typeof(TService)));
}
/// <summary>
/// Gets the services.
/// </summary>
/// <typeparam name="TService">The type of the service.</typeparam>
/// <param name="services">The services.</param>
/// <returns>The services.</returns>
/// <exception cref="System.ArgumentNullException">services</exception>
public static IEnumerable<TService> GetServices<TService>(this ServicesContainer services)
{
if (services == null)
{
throw new ArgumentNullException("services");
}
return services.GetServices(typeof(TService)).Cast<TService>();
}
}
The advantage of using this method is that it reuses the MetadataProvider and ValidatorProvider(s) you have configured for your Web API application while the previous answer is retrieving the one configured in ASP.NET MVC.
ASP.NET MVC and WebAPI run through different pipelines.
Turns out TryValidateModel is not supported in WebAPI. There's a feature request over on CodePlex.

what is the best way to implement a client side validation to check that the Max value is greater than the Min value inside my asp.net MVC

i have an object which contains Max value and Min value,, so i want inside all the edit and create views to display a client side validation message incase the user insert the Min value greater then the Min value.
BR
You will probably want both client-side and server-side validation. It might be good to implement your own Validation. I did a similar thing in which I wanted to make sure that one field was NOT the same value as another field. I didn't start from scratch though. I used some code from Simon J Ince of Microsoft. He has it here on his blog. Basically he has a foundation of Conditional Validation (where you validate based on the value of another field). I inherited from his ConditionalAttributeBase and implemented the IClientValidatable interface (this is how you send to the browser the dependent field the java script will check with.)
/// <summary>
/// A validator for ensuring that the value of this field does NOT equal the value of another field.
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
public class NotEqual:ConditionalAttributeBase, IClientValidatable
{
public string DependentProperty { get; set; }
/// <summary>
/// Returns client validation rules for NotEqual
/// </summary>
/// <param name="metadata">The model metadata.</param>
/// <param name="context">The controller context.</param>
/// <returns>
/// The client validation rules for NotEqual.
/// </returns>
IEnumerable<ModelClientValidationRule> IClientValidatable.GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
ValidationType = "notequal",
};
string depProp = BuildDependentPropertyId(metadata, context as ViewContext);
rule.ValidationParameters.Add("dependentproperty", depProp);
yield return rule;
}
/// <summary>
/// Builds the dependent property id.
/// </summary>
/// <param name="metadata">The metadata.</param>
/// <param name="viewContext">The view context.</param>
/// <returns></returns>
protected string BuildDependentPropertyId(ModelMetadata metadata, ViewContext viewContext)
{
return QualifyFieldId(metadata, DependentProperty, viewContext);
}
/// <summary>
/// Validates that the value does not equal the value of the dependent value if the dependent value is not null
/// </summary>
/// <param name="value">The value to validate.</param>
/// <param name="validationContext">The context information about the validation operation.</param>
/// <returns>
/// An instance of the <see cref="T:System.ComponentModel.DataAnnotations.ValidationResult"/> class.
/// </returns>
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// check if the current value matches the target value
if (value != null && GetDependentFieldValue(DependentProperty, validationContext).ToString() == value.ToString())
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
return ValidationResult.Success;
}
/// <summary>
/// Initializes a new instance of the <see cref="NotEqual"/> class.
/// </summary>
/// <param name="dependentProperty">The dependent property.</param>
public NotEqual(string dependentProperty)
{
DependentProperty = dependentProperty;
}
}$
Next I tweaked the javascript:
(function ($) {
$.validator.addMethod('notequal',
function (value, element, parameters) {
var id = '#' + parameters['dependentproperty'];
var depControl = $(id);
var control = $(element);
if (control.val() === depControl.val())
return "";
return true;
}
);
$.validator.unobtrusive.adapters.add(
'notequal',
['dependentproperty'],
function (options) {
options.rules['notequal'] = {
dependentproperty: options.params['dependentproperty']
};
options.messages['notequal'] = options.message;
}
);
$.validator.addMethod('notequaltwo',
function (value, element, parameters) {
var id = '#' + parameters['dependentproperty'];
var depControl = $(id);
var control = $(element);
if (control.val() === depControl.val())
return "";
return true;
}
);
$.validator.unobtrusive.adapters.add(
'notequaltwo',
['dependentproperty'],
function (options) {
options.rules['notequaltwo'] = {
dependentproperty: options.params['dependentproperty']
};
options.messages['notequaltwo'] = options.message;
}
);
})(jQuery);$
Hopefully you can see how you can adapt my code to do what you want it do, basically you would have to convert the types (if the types don't convert, don't do anything and other validators that you have should pick up on it.) and then do a compare.

Similar method to ResolveUrl for using from a static class?

I'm building a WebPart for Microsoft SharePoint 2010.
Which method could I use from a static class that does the same than ResolveUrl?
Take a look at this:
http://msdn.microsoft.com/en-us/library/system.web.virtualpathutility.aspx
You could make use of the ToAbsolute or ToAppRelative methods in order to simulate the functionality
http://www.west-wind.com/weblog/posts/2007/Sep/18/ResolveUrl-without-Page (in the comments)
/// <summary>
/// Returns a site relative HTTP path from a partial path starting out with a ~.
/// Same syntax that ASP.Net internally supports but this method can be used
/// outside of the Page framework.
///
/// Works like Control.ResolveUrl including support for ~ syntax
/// but returns an absolute URL.
/// </summary>
/// <param name="originalUrl">Any Url including those starting with ~</param>
/// <returns>relative url</returns>
public static string ResolveUrl(string originalUrl)
{
if (string.IsNullOrEmpty(originalUrl))
return originalUrl;
// *** Absolute path - just return
if (IsAbsolutePath(originalUrl))
return originalUrl;
// *** We don't start with the '~' -> we don't process the Url
if (!originalUrl.StartsWith("~"))
return originalUrl;
// *** Fix up path for ~ root app dir directory
// VirtualPathUtility blows up if there is a
// query string, so we have to account for this.
int queryStringStartIndex = originalUrl.IndexOf('?');
if (queryStringStartIndex != -1)
{
string queryString = originalUrl.Substring(queryStringStartIndex);
string baseUrl = originalUrl.Substring(0, queryStringStartIndex);
return string.Concat(
VirtualPathUtility.ToAbsolute(baseUrl),
queryString);
}
else
{
return VirtualPathUtility.ToAbsolute(originalUrl);
}
}
/// <summary>
/// This method returns a fully qualified absolute server Url which includes
/// the protocol, server, port in addition to the server relative Url.
///
/// Works like Control.ResolveUrl including support for ~ syntax
/// but returns an absolute URL.
/// </summary>
/// <param name="ServerUrl">Any Url, either App relative or fully qualified</param>
/// <param name="forceHttps">if true forces the url to use https</param>
/// <returns></returns>
public static string ResolveServerUrl(string serverUrl, bool forceHttps)
{
if (string.IsNullOrEmpty(serverUrl))
return serverUrl;
// *** Is it already an absolute Url?
if(IsAbsolutePath(serverUrl))
return serverUrl;
string newServerUrl = ResolveUrl(serverUrl);
Uri result = new Uri(HttpContext.Current.Request.Url, newServerUrl);
if (!forceHttps)
return result.ToString();
else
return ForceUriToHttps(result).ToString();
}
/// <summary>
/// This method returns a fully qualified absolute server Url which includes
/// the protocol, server, port in addition to the server relative Url.
///
/// It work like Page.ResolveUrl, but adds these to the beginning.
/// This method is useful for generating Urls for AJAX methods
/// </summary>
/// <param name="ServerUrl">Any Url, either App relative or fully qualified</param>
/// <returns></returns>
public static string ResolveServerUrl(string serverUrl)
{
return ResolveServerUrl(serverUrl, false);
}
/// <summary>
/// Forces the Uri to use https
/// </summary>
private static Uri ForceUriToHttps(Uri uri)
{
// ** Re-write Url using builder.
UriBuilder builder = new UriBuilder(uri);
builder.Scheme = Uri.UriSchemeHttps;
builder.Port = 443;
return builder.Uri;
}
private static bool IsAbsolutePath(string originalUrl)
{
// *** Absolute path - just return
int IndexOfSlashes = originalUrl.IndexOf("://");
int IndexOfQuestionMarks = originalUrl.IndexOf("?");
if (IndexOfSlashes > -1 &&
(IndexOfQuestionMarks < 0 ||
(IndexOfQuestionMarks > -1 && IndexOfQuestionMarks > IndexOfSlashes)
)
)
return true;
return false;
}

Resources