In my C# application I use 2 connection strings (application_cs, users_cs). To change these connection strings I use:
private static void SetProviderConnectionString(string connectionString)
{
var connectionStringFieldM =
Membership.Provider.GetType().GetField("_sqlConnectionString",
BindingFlags.Instance | BindingFlags.NonPublic);
var connectionStringFieldR = Roles.Provider.GetType().GetField("_sqlConnectionString",
BindingFlags.Instance | BindingFlags.NonPublic);
var connectionStringFieldP = ProfileManager.Provider.GetType().GetField("_sqlConnectionString",
BindingFlags.Instance | BindingFlags.NonPublic);
connectionStringFieldM.SetValue(Membership.Provider, connectionString);
connectionStringFieldR.SetValue(Roles.Provider, connectionString);
connectionStringFieldP.SetValue(ProfileManager.Provider, connectionString);
}
public static void SetProviderUsers()
{
SetProviderConnectionString(ConfigurationManager.ConnectionStrings["users_cs"].ConnectionString);
}
public static void SetProviderApp()
{
SetProviderConnectionString(ConfigurationManager.ConnectionStrings["application_cs"].ConnectionString);
}
So in my code whenever I want to add a user I do this:
public int CreateUser(int stid, int cid, int usrId, string email, string tel, string mob, string username,
bool create, bool prime)
{
int result = 0;
Guid userid = new Guid();
DALUsers.UserDBDataContext dc = new DALUsers.UserDBDataContext();
DAL.AppDataContext d = new DAL.AppDataContext();
BLL.Security.SetProviderUsers();
if (create) //create the user first
{
string question = "1";
string answer = "1";
bool isAproved = true;
string password = System.Web.Security.Membership.GeneratePassword(8, 2);
MembershipCreateStatus cs = new MembershipCreateStatus();
MembershipUser newUser = Membership.CreateUser(username, password, email, question, answer, isAproved, out cs);
Membership.UpdateUser(newUser);
Roles.AddUserToRole(username, "User_x");
if (cs == MembershipCreateStatus.Success)
{
result = 1;
}
else
X.MessageBox.Info("Error", "Cannot create user due to :" + cs.ToString(), UI.Danger).Show();
}
//at this point we have the user created either way.
// return userid;
var id = (from i in dc.aspnet_Users where i.UserName.CompareTo(username) == 0 select i.UserId);
if (id.Count() == 1)
{
userid = id.First();
bool contin = true;
var fulname = (from i in dc.Clients where i.id == usrId select i).First();
if (String.IsNullOrEmpty(fulname.Mobile)) fulname.Mobile = mob;
fulname.Email = email;
fulname.ModifiedBy = HttpContext.Current.User.Identity.Name;
fulname.ModifiedDate = DateTime.Now;
dc.SubmitChanges();
DateTime dt = DateTime.Now;
DALUsers.CIUser usr = new DALUsers.CIUser();
var existing = (from i in dc.CIUsers where i.UserName.CompareTo(username) == 0 && i.cid == cid select i);
if (existing.Count() > 0)
{
X.MessageBox.Info("Warning", "UserName already exists . Please try another!", UI.Warning).Show();
contin = false;
}
else
{
dc.CIUsers.InsertOnSubmit(usr);
dc.SubmitChanges();
}
if (contin)
{
DALUsers.CIUser usrNew = new DALUsers.CIUser();
var approved = (from k in dc.aspnet_Memberships //if user is not approved
where k.UserId == userid
select k).FirstOrDefault();
if (approved.IsApproved == false)
{
approved.IsApproved = true;
}
ProfileBase profile = ProfileBase.Create(username);
profile.SetPropertyValue("Mobile", mob);
profile.SetPropertyValue("Email", email);
profile.Save();
usrNew.UserId = usrId;
usrNew.cid = cid;
usrNew.FullName = fulname.LastName + " " + fulname.FirstName;
usrNew.Role = "User_x";
usrNew.SignRights = prime;
usrNew.IsPrime = prime;
usrNew.stid = stid;
usrNew.UserName = username;
usrNew.UserId = userid;
usrNew.CreatedDate = DateTime.Now;
usrNew.CreatedBy = HttpContext.Current.User.Identity.Name;
dc.CIUsers.InsertOnSubmit(usrNew);
dc.SubmitChanges();
result = 1;
X.MessageBox.Info("Success", "The user has been successfully added", UI.Success).Show();
}
}
else
X.MessageBox.Info("Error", "Could not find the user", UI.Danger).Show();
BLL.Security.SetProviderApp();
return result;
}
EDIT
I just saw that in my code there is this line:
DALUsers.aspnet_User user = new DALUsers.aspnet_User();
But the variable user is not used anywhere else in the code. Probably it has been left there... And its the only variable named user in my code. Is that causing the issue? But then why only on the production server?
EDIT
The weird part is that when I run my application from visual studio locally it works as a charm. But when I am adding a user in the application running on the production server when I am trying to add the second user it fails and I receive this error:
Value cannot be null. Parameter name: user
And if I try to login to my application after that it fails. I have to restart my website from iis to be able to login again.
Any ideas?
Well I cant find the error in your code but if you say that this error occurs only in server and that you are sure that your files are synched between server and your local machine, then probably the error lies in your web.config. Take a look
Related
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
I have a web application that uses Active Directory to authenticate. I want to add an option that will notify the users when their password is close to expiring.
I managed to do something, but the problem I have is that the expiration days is negative (daysLeft parameter), yet I can still log in.
string domainAndUsername = #"LDAP://ldapUrl";
DirectoryEntry root = new DirectoryEntry(ldapServer, userID, userPwd, AuthenticationTypes.Secure);
DirectorySearcher mySearcher = new DirectorySearcher(root);
SearchResultCollection results;
string filter = "maxPwdAge=*";
mySearcher.Filter = filter;
results = mySearcher.FindAll();
long maxDays = 0;
if (results.Count >= 1)
{
Int64 maxPwdAge = (Int64)results[0].Properties["maxPwdAge"][0];
maxDays = maxPwdAge / -864000000000;
}
mySearcher = new DirectorySearcher(root);
mySearcher.Filter = "(&(objectCategory=user)(samaccountname=" + userID + "))";
results = mySearcher.FindAll();
long daysLeft = 0;
if (results.Count >= 1)
{
var lastChanged = results[0].Properties["pwdLastSet"][0];
daysLeft = maxDays - DateTime.Today.Subtract(
DateTime.FromFileTime((long)lastChanged)).Days;
}
Since a user couldn't log in if it's account has expired, I am guessing my error is in calculating the days left until account expires...but I can't seem to find where it is.
This snippet works correctly, I have three days left to change my pw, including today:
public static void Main(string[] args)
{
const ulong dataFromAD = 0xFFFFE86D079B8000;
var ticks = -unchecked((long)dataFromAD);
var maxPwdAge = TimeSpan.FromTicks(ticks);
var pwdLastSet = new DateTime(2015,12,16,9,19,13);
var pwdDeadline = (pwdLastSet + maxPwdAge).Date;
Console.WriteLine(pwdDeadline);
Console.WriteLine(pwdDeadline - DateTime.Today);
Console.ReadKey(true);
}
I also verified that TimeSpan.FromTicks(-(long)results[0].Properties["maxPwdAge"][0]) and DateTime.FromFileTime((long)results[0].Properties["pwdLastSet"][0]) are expressions correctly extracting the values from our AD.
I've used the following code in the past, and i think it's accurate. You may try it and see if it works for you:
private static DateTime? getPwdExpiration(string usuario)
{
DirectoryEntry searchGroup = new DirectoryEntry("LDAP://ldapUrl");
DateTime? dt=null;
foreach (DirectoryEntry user in searchGroup.Children)
{
if (user.InvokeGet("userPrincipalName") != null)
{
string username = user.InvokeGet("userPrincipalName").ToString();
username = username.Substring(0, username.IndexOf('#'));
if (username == usuario)
{
if (user.InvokeGet("PasswordExpirationDate") != null)
{
dt = (DateTime)user.InvokeGet("PasswordExpirationDate");
if (dt.Value.CompareTo(new DateTime(1970,1,1))==0)
{
//Password never expires
dt = null;
}
}
break;
}
}
}
return dt;
}
Usage:
DateTime? expirationDate = getPwdExpiration(username);
With Node JS you can achieve the password expiry. Try Something like this
const modifyChange = [
new ldap.Change({
operation: 'replace',
modification: {
pwdMaxAge: 3600 //in seconds
}
})];
client.modify('cn=Manager,dc=mydomain,dc=local', modifyChange, (err) => {
if(!err) {
console.log('password age updated')// updated
}
});
I have this in my button click event:
protected void btn_login_Click(object sender, EventArgs e)
{
authentication auth = new authentication();
bool emailExists = auth.checkEmail(System.Convert.ToString(txt_email.Text));
if (emailExists == true)
{
btn_create.Text = "Email doesnt exist";
}
else
{
btn_create.Text = "Email exists";
}
}
It sends the email to my checkEmail method which is in my authentication class:
public bool checkEmail(string email)
{
bool emailExists = false;
usersTableAdapters.UsersTableAdapter user = new usersTableAdapters.UsersTableAdapter();
users.UsersDataTable userDataTable = user.checkEmail(email);
if (userDataTable.Rows.Count == 0)
{
emailExists = false;
}
else
{
emailExists = true;
}
return emailExists;
}
The checkEmail query is "SELECT COUNT(email) AS email FROM People WHERE (email = ?)"
However when I debug, it always falls through the if(emailExists == true) statement even when the email already exists in my DB, does anyone know why?
your query you entered will always have 1 result. If you want to continue using that query, you should check the first column ("email") of the first result and check to see if that is == 0 or not.
can't add code markup in comments, so reposting how I would rewrite the checkEmail method: (assuming the how the UsersTableAdapter type is setup)
public bool checkEmail(string email)
{
usersTableAdapters.UsersTableAdapter user = new usersTableAdapters.UsersTableAdapter();
users.UsersDataTable userDataTable = user.checkEmail(email);
return userDataTable.Rows[0][0] > 0;
}
I figured out I would have to check the index of the row which in this case is 0 and then retrieve and store the value from the email column into an int
DataRow row = userDataTable.Rows[0];
int rowValue = System.Convert.ToInt16(row["email"]);
I have the following code(facebook C# SDK) to post to facebook wall :
public long? UploadPost(string intLinkTitle, string inMessage, string inLinkCaption, string inLinkUrl, string inLinkDescription, string inLinkUrlPicture)
{
object obj;
Facebook.JsonObject jsonObj;
FacebookClient client;
string access_token = ConfigurationManager.AppSettings["FacebookPageAccessToken"].ToString();
client = new FacebookClient(access_token);
var args = new Dictionary<string, object>();
args["message"] = inMessage;
args["caption"] = inLinkCaption;
args["description"] = inLinkDescription;
args["name"] = intLinkTitle;
args["picture"] = inLinkUrlPicture;
args["link"] = inLinkUrl;
if ((obj = client.Post("/" + ConfigurationManager.AppSettings["FacebookPageId"].ToString() + "/feed", args)) != null)
{
if ((jsonObj = obj as Facebook.JsonObject) != null)
{
if (jsonObj.Count > 0)
return long.Parse(jsonObj[0].ToString().Split('_').Last().ToString());
}
}
return null;
}
}
This works great as long as I post to my public facebook website page but when changing the FacebookPageId to a group id instead I get (FacebookApiException - #200) Permissions error.
My user are admin of both the group and the page.
I have tried to post the message from the Graph API Explorer with the following line : 294632750660619/feed/?message=test but there is a syntax problem here, have also tried 294632750660619/feed?message=test but with no success.
How do I post to the closed facebook group?
Okay, I found the correct way. This is what I hade to do :
Go to the https://developers.facebook.com/ and create a new application
Settings > Add platform(Website and set the site URL(for example localhost..)
Set the app to go live(status & review > Yes), to do this a email adress needs to be set under settings > Contact Email
Go to the Graph API Explorer
Choose the new app from the dropdown
Click Get Access Token
Choose correct permissions(user_groups, user_status, user_photos, manage_pages, publish_actions, read_insights and read_stream) and click Get Access Token. Now we bot a short lived tooken
Generate a extended user token (valid for 60 days) by using this URL(change parameters(3)) : https://graph.facebook.com/oauth/access_token?grant_type=fb_exchange_token&client_id=[app-id]&client_secret=[app-secret]&fb_exchange_token=[short-lived-token]
Use the generated none expiring access token in the application
Validate the Access token here : https://developers.facebook.com/tools/debug/access_token/
Use this code to upload post :
public long? UploadPost(string intLinkTitle, string inMessage, string inLinkCaption, string inLinkUrl, string inLinkDescription, string inLinkUrlPicture)
{
object obj;
Facebook.JsonObject jsonObj;
FacebookClient client;
string access_token = ConfigurationManager.AppSettings["FacebookPageAccessToken"].ToString();
client = new FacebookClient(access_token);
var args = new Dictionary<string, object>();
args["message"] = inMessage;
args["caption"] = inLinkCaption;
args["description"] = inLinkDescription;
args["name"] = intLinkTitle;
args["picture"] = inLinkUrlPicture;
args["link"] = inLinkUrl;
if ((obj = client.Post("/" + ConfigurationManager.AppSettings["FacebookPageId"].ToString() + "/feed", args)) != null)
{
if ((jsonObj = obj as Facebook.JsonObject) != null)
{
if (jsonObj.Count > 0)
return long.Parse(jsonObj[0].ToString().Split('_').Last().ToString());
}
}
return null;
}
And to get feed, use this :
private void GetFeed()
{
object obj;
Facebook.JsonObject jsonObj;
Facebook.JsonObject jsonPaging;
FacebookClient client;
int pageCount = 0;
string access_token;
string URL;
DateTime fetchFaceBookFeedFromDate;
DateTime? oldestPostFetched = null;
fetchFaceBookFeedFromDate = DateTime.Now.AddDays(-30);
access_token = ConfigurationManager.AppSettings["FacebookPageAccessToken"].ToString();
URL = "/" + ConfigurationManager.AppSettings["FacebookPageId"].ToString() + "/feed";
client = new FacebookClient(access_token);
while (URL.Length > 0 && pageCount < 1000)
{
if ((obj = client.Get(URL)) != null)
{
if ((jsonObj = obj as Facebook.JsonObject) != null && jsonObj.Count > 0)
{
if (jsonObj[0] is Facebook.JsonArray)
oldestPostFetched = SaveFacebookForumThread(jsonObj[0] as Facebook.JsonArray, fetchFaceBookFeedFromDate);
if (jsonObj.Keys.Contains("paging") && (jsonPaging = jsonObj["paging"] as Facebook.JsonObject) != null && jsonPaging.Keys.Contains("next"))
URL = jsonPaging["next"].ToString();
else
break;
}
}
pageCount++;
if (oldestPostFetched.HasValue && fetchFaceBookFeedFromDate > oldestPostFetched)
break;
}
}
I'm still very new to C# and would appreciate any help with my code.
I'm creating a user profile page and am getting the error "Nullable object must have a value" on "photo = (byte)user.Photo;" in the following code. I assume it's because I declared "photo = 0;" How do I add a value to it?
Update:
Here's the entire method
public static bool UserProfile(string username, out string userID, out string email, out byte photo)
{
using (MyDBContainer db = new MyDBContainer())
{
userID = "";
photo = 0;
email = "";
User user = (from u in db.Users
where u.UserID.Equals(username)
select u).FirstOrDefault();
if (user != null)
{
photo = (byte)user.Photo;
email = user.Email;
userID = user.UserID;
return true; // success!
}
else
{
return false;
}
}
}
I am assuming that you are getting error for this one...
if (user != null)
{
photo = (byte)user.Photo;
email = user.Email;
userID = user.UserID;
return true; // success!
}
else
{
return false;
}
If yes then just replace it with...
if (user != null)
{
photo = user.Photo== null ? null : (byte)user.Photo;
email = user.Email;
userID = user.UserID;
return true; // success!
}
else
{
return false;
}