I am trying to add bindings to a website in IIS with C# code. It seem to work on my local computer, but not on the hosting server (Windows Server 2022). Adding http-binding works, but commit after https causes NullReferenceException, and i am wondering if any of you can explain to me why?
My code is like this (i replaced my actual domainname with . "sitename" and "hostHttpsBinding" always exists with the certificate i want to use):
public static bool AddBindings(IConfiguration configuration, ILogger logger, string subdomain)
{
if (string.IsNullOrWhiteSpace(subdomain)) return false;
try
{
var server = new ServerManager();
var sitename = EnvironmentHelper.IsProd(configuration) ? "<domain>.no" : "test.<domain>.no";
var hostname = $"{subdomain.ToLowerInvariant().Trim()}.<domain>.no";
var site = server.Sites.FirstOrDefault(a => a.Name == sitename);
if (site == null) return false;
logger.LogInformation($"IIS: Sitename {sitename} found. Trying to add bindings...");
var hostHttpsBinding = site.Bindings.FirstOrDefault(a => a.BindingInformation == $"*:443:{sitename}");
var httpBinding = site.Bindings.FirstOrDefault(a => a.BindingInformation == $"*:80:{hostname}");
var httpsBinding = site.Bindings.FirstOrDefault(a => a.BindingInformation == $"*:443:{hostname}");
if (httpBinding != null && httpsBinding != null) return false;
if (httpBinding == null)
{
site.Bindings.Add($"*:80:{hostname}", "http");
logger.LogInformation($"IIS: Http-binding added for {hostname}");
}
if (httpsBinding == null)
{
logger.LogInformation($"SSLName: {hostHttpsBinding.CertificateStoreName}, Hash: {hostHttpsBinding.CertificateHash}");
site.Bindings.Add($"*:443:{hostname}", hostHttpsBinding.CertificateHash, hostHttpsBinding.CertificateStoreName, SslFlags.Sni);
logger.LogInformation($"IIS: Https-binding added for {hostname}");
}
server.CommitChanges();
server.Dispose();
return true;
}
catch (Exception e)
{
logger.LogError($"IIS: Something went wrong when adding bindings: {e.Message}, {e.InnerException.Message}");
return false;
}
}
This is my error message:
ERROR|Microsoft.AspNetCore.Server.IIS.Core.IISHttpServer|Connection ID "16717361851964326032", Request ID "40000091-0008-e800-b63f-84710c7967bb": An unhandled exception was thrown by the application.|System.NullReferenceException: Object reference not set to an instance of an object.
Related
I have login controller and in this i get my session values
[HttpPost]
public ActionResult Login(Models.AdminUsers adminUsers)
{
try
{
if (Session["iUserId"] != null || GetCookie("iUserId") != null)
{
return Redirect("/Home/Index");
}
if (ModelState.IsValid)
{
using (Data.DataClassesDataContext dc = new Data.DataClassesDataContext())
{
var resultUsers =
(from tableAdminUsers in dc.AdminUsers
where
tableAdminUsers.cEmail == adminUsers.cEmail &&
tableAdminUsers.cPassaword == new Class.AesCryption().Encryption(adminUsers.cPassaword) &&
tableAdminUsers.iActive == 1
select new Models.AdminUsers
{
iUserId = tableAdminUsers.iUserId,
cEmail = tableAdminUsers.cEmail,
cUserName = tableAdminUsers.cUserName,
cUserSurname = tableAdminUsers.cUserSurname,
cImage = tableAdminUsers.cImage
}).FirstOrDefault();
if (resultUsers != null)
{
if (adminUsers.lBeniHatirla == false)
{
Session.Add("iUserId", resultUsers.iUserId);
Session.Add("cEmail", resultUsers.cEmail);
Session.Add("cUserName", new Class.TextLowerAndFirstUpper().Send(resultUsers.cUserName));
Session.Add("cUserSurname", resultUsers.cUserSurname.ToUpper());
Session.Add("cImage", resultUsers.cImage);
}
else
{
CreateCookie("iUserId", resultUsers.iUserId.ToString());
CreateCookie("cEmail", resultUsers.cEmail);
CreateCookie("cUserName", new Class.TextLowerAndFirstUpper().Send(resultUsers.cUserName));
CreateCookie("cUserSurname", resultUsers.cUserSurname.ToUpper());
CreateCookie("cImage", resultUsers.cImage);
}
return Redirect("/Home/Index");
}
else
{
ViewBag.iSonuc = -7;
}
}
}
else
{
ViewBag.iSonuc = -6;
}
}
catch (Exception Ex)
{
new Class.Log().Hata("AdminUsers", "AdminUsers_Post", Ex.Message);
}
return View();
}
And i want to control to session in another controller but my session value return null. My control like this :
if (Session["iUserId"] == null && GetCookie("iUserId") == null)
{
return Redirect("/AdminUsers/Login");
}
int iUserLogin = 0;
if (Session["iUserId"] != null && Convert.ToInt32(Session["iUserId"]) > 0)
{
iUserLogin = Convert.ToInt32(Session["iUserId"]);
}
else if (GetCookie("iUserId") != null && Convert.ToInt32(GetCookie("iUserId")) > 0)
{
iUserLogin = Convert.ToInt32(GetCookie("iUserId"));
}
if (Session["iUserId"] == null && GetCookie("iUserId") == null) this row return true and redict to login page again.But i getting cookie correctly Why session value return null?
Where am I making mistakes? Can you help me?
If it is a .net core, use httpcontext. You can solve it using a distribution cache such as Redis. https://learn.microsoft.com/tr-tr/aspnet/core/fundamentals/app-state?view=aspnetcore-5.0
If you want to develop a User Manager
Use a thirty part nuget like Jwt. What it does is sso logic gives you a token for the user you use it
Try using Session with HttpContext as below:-
HttpContext.Current.Session["iUserId"]=value;
Alternativly, you can try using TempData rather then Session.
TempData["iUserId"]=value;
There is a localization function that I use for language change, in this function I am changing the value of the culture using thread, I realized that this function resets my session value.
We’re having a problem to access a value we stored previously in keychain in a previous version of our app. We have updated our Xamarin.iOS version from 11.6.14 to 12.2.1.15 and our XCode version from 9.4.1 to 10.1.
We are not able to access that value anymore after the update.
I have read there are some changes in the security settings, but I’m not able to find the specifics about that. Is there anybody that had that problem before or has lot of experience with keychain? Thanks for your help!
bool WriteGenericPasswordValueToSecureKeychain(string service, string account, string value)
{
if (service == null || account == null || value == null)
{
throw new ArgumentNullException("Both arguments need a value and cannot be null");
}
var query = new SecRecord(SecKind.GenericPassword)
{
Service = service,
Account = account
};
var newRecord = new SecRecord(SecKind.GenericPassword)
{
Service = service,
Account = account,
ValueData = NSData.FromString(value, NSStringEncoding.UTF8)
};
SecStatusCode error;
var match = SecKeyChain.QueryAsRecord(query, out error);
if (error == SecStatusCode.Success)
{
error = SecKeyChain.Update(match, newRecord);
}
else
{
error = SecKeyChain.Add(newRecord);
}
if (error != SecStatusCode.Success && error != SecStatusCode.DuplicateItem)
{
return false;
}
return true;
}
For example i have this method:
public static bool IsConnectedMobile
{
get
{
var info = ConnectivityManagers.ActiveNetworkInfo;
return info != null && info.IsConnected && info.Type == ConnectivityType.Mobile;
}
}
and i get an error here: info.Type == ConnectivityType.Mobile;
And my question is, can i found an alternative? (without using other libraries)
ActiveNetworkInfo you need get it from GetSystemService Just use this code
ConnectivityManager cm = (ConnectivityManager)this.GetSystemService(Context.ConnectivityService);
NetworkInfo activeNetwork = cm.ActiveNetworkInfo;
if (activeNetwork != null)
{
//connected to the internet
}
else
{
//not connected to the internet
}
& for more information go through this thread
This feature is platform-specific. Basically you can check the Network Connection status by using the below code:
var cm = (ConnectivityManager)GetSystemService(Context.ConnectivityService);
bool isConnected = cm.ActiveNetworkInfo.IsConnected;
Should be quite straightforward.
Thanks.
I'm trying to figure out what is causing a crash in our Outlook plugin. We're seeing this error:
System.Runtime.InteropServices.COMException (0x8E640201): An internal support function returned an error.
at Microsoft.Office.Interop.Outlook.AddressEntry.get_AddressEntryUserType()
at DropSendOutlook.RecipientAddressGetter.GetSmtpAddress(AddressEntry addressEntry)
at DropSendOutlook.RecipientAddressGetter.<Get>b__0(Recipient recipient)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.<DistinctIterator>d__64`1.MoveNext()
at System.String.Join(String separator, IEnumerable`1 values)
at DropSendOutlook.RecipientAddressGetter.Get(MailItem mail)
at DropSendOutlook.ThisAddIn.outlookApp_ItemSend(Object item, Boolean& cancel)
Based on this stack trace, it's clear the problem is in this function:
private static string GetSmtpAddress(AddressEntry addressEntry)
{
var addressEntryUserType = addressEntry.AddressEntryUserType;
Log.Info(addressEntryUserType);
//Now we have an AddressEntry representing the Sender
if (addressEntryUserType == OlAddressEntryUserType.olExchangeUserAddressEntry
|| addressEntryUserType == OlAddressEntryUserType.olExchangeRemoteUserAddressEntry)
{
//Use the ExchangeUser object PrimarySMTPAddress
ExchangeUser exchUser = addressEntry.GetExchangeUser();
return exchUser != null ? exchUser.PrimarySmtpAddress : GetSmtpAddressExchangeOld(addressEntry);
}
if (addressEntryUserType == OlAddressEntryUserType.olSmtpAddressEntry)
{
return addressEntry.Address;
}
if (addressEntryUserType == OlAddressEntryUserType.olOutlookContactAddressEntry)
{
// Could throw System.Runtime.InteropServices.COMException (0x8004010F), possible reasons with permissions.
try
{
try
{
var contact = addressEntry.GetContact();
if (contact != null && contact.Email1AddressType == "EX")
{
var currentDisplayName = contact.Email1DisplayName;
contact.Email1DisplayName = string.Empty;
var separators = new[] { '(', ')' };
var eMailParse = contact.Email1DisplayName.Split(separators);
contact.Email1DisplayName = currentDisplayName;
return eMailParse[1];
}
}
catch
{
var ms = new FrmMessage();
ms.SetMessage("Contact was not found!");
ms.Show();
throw;
}
}
catch (System.Exception ex)
{
Log.Error(ex.ToString());
}
return addressEntry.Address;
}
if (addressEntryUserType == OlAddressEntryUserType.olExchangeDistributionListAddressEntry)
{
var exchDistribution = addressEntry.GetExchangeDistributionList();
return exchDistribution != null
? exchDistribution.PrimarySmtpAddress
: GetSmtpAddressExchangeOld(addressEntry);
}
if (addressEntryUserType == OlAddressEntryUserType.olOutlookDistributionListAddressEntry)
{
var addresses = from AddressEntry member in addressEntry.Members select GetSmtpAddress(member);
return string.Join(";", addresses);
}
return addressEntry.Address;
}
And appears to be coming from this line specifically:
var addressEntryUserType = addressEntry.AddressEntryUserType;
What is causing this? Is there some kind of check we should be making before accessing AddressEntryUserType to avoid this error?
Has anybody ever had an issue where the SessionModSvcContractClient Logout function throws an Exception: Additional information:
Object reference not set to an instance of an object.
When I tried LogoutAsync and Close methods they worked fine.
Can anybody help me figure out why that's happening or the difference between the 3.
I'm basically trying to use create the test from the WCF guide
static void Main(string[] args)
{
//use a self-signed certificate in IIS, be sure to include the following code. This code speeds up calls to the services and prevents the method from trying to validate the certificate with the known authorities.
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, errors) => { return true; };
//You can toggle the value assigned to this variable to test the two bindings: SOAPHttp or BasicHttp
EndpointBindingType bindingType = EndpointBindingType.SOAPHttp;
//Epicor credentials:
string epicorUserID = "XXX";
string epiorUserPassword = "XXX";
string scheme = "http";
if (bindingType == EndpointBindingType.BasicHttp)
{
scheme = "https";
}
UriBuilder builder = new UriBuilder(scheme, "localhost");
string webServicesLink = "XXX/";
builder.Path = webServicesLink + "Ice/Lib/SessionMod.svc";
SessionModSvcContractClient sessionModClient = GetClient < SessionModSvcContractClient, SessionModSvcContract > (builder.Uri.ToString(), epicorUserID, epiorUserPassword, bindingType);
builder.Path = webServicesLink + "Erp/BO/AbcCode.svc";
ABCCodeSvcContractClient abcCodeClient = GetClient<ABCCodeSvcContractClient, ABCCodeSvcContract>(builder.Uri.ToString(), epicorUserID, epiorUserPassword, bindingType);
Guid sessionId = Guid.Empty;
sessionId = sessionModClient.Login();
//Create a new instance of the SessionModSvc. Do this because when you call any method on the service
//client class, you cannot modify its Endpointbehaviors.
builder.Path = webServicesLink + "Ice/Lib/SessionMod.svc";
sessionModClient = GetClient < SessionModSvcContractClient, SessionModSvcContract > (builder.Uri.ToString(),epicorUserID,epiorUserPassword,bindingType);
sessionModClient.Endpoint.EndpointBehaviors.Add(new HookServiceBehavior(sessionId, epicorUserID));
abcCodeClient.Endpoint.EndpointBehaviors.Add(new HookServiceBehavior(sessionId, epicorUserID));
var ts = new ABCCodeTableset();
abcCodeClient.GetNewABCCode(ref ts);
var newRow = ts.ABCCode.Where(n => n.RowMod.Equals("A", StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
if (newRow != null)
{
newRow.ABCCode = "G";
newRow.CountFreq = 30;
newRow.StockValPcnt = 100;
abcCodeClient.Update(ref ts);
ts = null;
ts = abcCodeClient.GetByID("G");
if (ts != null && ts.ABCCode.Any())
{
ABCCodeRow backupRow = new ABCCodeRow();
var fields = backupRow.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
foreach (var field in fields)
{
if (field.PropertyType == typeof(System.Runtime.Serialization.ExtensionDataObject))
{
continue;
}
var fieldValue = field.GetValue(ts.ABCCode[0]);
field.SetValue(backupRow, fieldValue);
}
ts.ABCCode.Add(backupRow);
ts.ABCCode[0].CountFreq = 45;
ts.ABCCode[0].RowMod = "U";
abcCodeClient.Update(ref ts);
ts = null;
ts = abcCodeClient.GetByID("G");
if (ts != null && ts.ABCCode.Any())
{
Console.WriteLine("CountFreq = {0}", ts.ABCCode[0].CountFreq);
ts.ABCCode[0].RowMod = "D";
abcCodeClient.Update(ref ts);
try
{
ts = abcCodeClient.GetByID("G");
}
catch (FaultException<Epicor.AbcCodeSvc.EpicorFaultDetail> ex)
{
if (ex.Detail.ExceptionKindValue.Equals("RecordNotFound", StringComparison.InvariantCultureIgnoreCase))
{
Console.WriteLine("Record deleted.");
}
else
{
Console.WriteLine(ex.Message);
}
}
}
}
}
if (sessionId != Guid.Empty)
{
sessionModClient.Logout();
}
Console.ReadLine();
}
Your code worked fine for me after I changed the config to suit my environment.
It looks like you followed the step 7 on page 15 of the Epicor10_techrefWCFServices_101400.pdf guide and correctly created a new instance of the SessionModSvc after Login(). However, if you copied the full code for the Main method from page 18 then this is missing and I can replicate your issue.
Check the code that you are compiling has created a new instance of the SessionModSvc after the call to .Login().
See my other answer, but as an alternative you may want to consider this method of accessing the services.
If you have access to the client DLLs then this code might be easier:
static void Main(string[] args)
{
// Hard-coded LogOn method
// Reference: Ice.Core.Session.dll
Ice.Core.Session session = new Ice.Core.Session("manager", "manager", "net.tcp://AppServer/MyCustomerAppserver-99999-10.0.700.2");
// References: Epicor.ServiceModel.dll, Erp.Contracts.BO.ABCCode.dll
var abcCodeBO = Ice.Lib.Framework.WCFServiceSupport.CreateImpl<Erp.Proxy.BO.ABCCodeImpl>(session, Erp.Proxy.BO.ABCCodeImpl.UriPath);
// Call the BO methods
var ds = abcCodeBO.GetByID("A");
var row = ds.ABCCode[0];
System.Console.WriteLine("CountFreq is {0}", row.CountFreq);
System.Console.ReadKey();
}
Just add references to:
Ice.Core.Session.dll
Epicor.ServiceModel.dll
Erp.Contracts.BO.ABCCode.dll