I've noticed that if you try to send an email to an invalid address, an exception is raised:
MailAddress To=new MailAddress("invalidemailaddress","recipientname");
throws:
"The specified string is not in the form required for an e-mail address"
This means that there must be a .Net function which is executed in MailAddress to check if the email address is valid or not. Is there a way to call this 'validate' function directly? This way I won't need to create my own IsValid function.
No but you can make one:
public bool ValidateEmailAddress (string email)
{
if (string.IsNullOrEmpty (email)) return false;
try
{
MailAddress to = new MailAddress (email);
return true;
}
catch (WhateverException e)
{
return false;
}
}
Answering comments. I am aware this technique is regarded as a bad one and with reason. What I would like to point out is that this approach will give you 100% guarantee the .NET mailing library will be able to send to a validated address lately. The problem with Regexes (of which there are plenty) is that each one addresses one particular subset of the set of technically correct addresses as per specification. One would be narrower, the other one would be wider than the subset defined internally in .NET. If you were to use Regex validation, then in the first case your Regex would cut off a portion of the valid addresses (as seen by .NET), in the latter case the validaton will let through addresses that the .NET mailing library won't treat as invalid per its own internal validation. The one true way to make sure you valid set 100% matches the .NET set (or of any other third party library you would use) is to fall for the try/catch approach, unless of course this third party library offers some validation method already.
Yes, there is such a .Net function, but its functionality is unaccessible by "standard" means: MailAdress uses a private ParseAddress method, which in turn uses System.Net.Mime.MailBnfHelper. The latter is an internal class, so it's not (easily) accessible outside the framework itself.
Thus, the only way to use these functions would be to use reflection, which I strongly advise against. Since these functions are undocumented and unaccessible without reflection, their implementation might change and your code might break in future versions of the framework.
There's a good example of an email validation function on CodeProject.
Original Source Code written by Vasudevan Deepak Kumar:
public static bool isEmail(string inputEmail)
{
inputEmail = NulltoString(inputEmail);
string strRegex = #"^([a-zA-Z0-9_\-\.]+)#((\[[0-9]{1,3}" +
#"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" +
#".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
Regex re = new Regex(strRegex);
if (re.IsMatch(inputEmail))
return (true);
else
return (false);
}
Unfortunately, there is no way to get at that functionality without reverse-engineering it or using that specific exception, sadly.
The traditional way to validate an email address has always been with regular expressions, but there are lengths you can go beyond that to validate emails even further, if you so wish:
The Forgotten Art of Email Address Validation
You could write your own class:
class EmailAddress
{
private MailAddress _email;
public string Address
{
get
{
return _email == null ? string.Empty : _email.Address;
}
}
public string DisplayName
{
get
{
return _email == null ? string.Empty : _email.DisplayName;
}
}
public string Host
{
get
{
return _email == null ? string.Empty : _email.Host;
}
}
public string User
{
get
{
return _email == null ? string.Empty : _email.User;
}
}
public EmailAddress(string email)
{
try {
_email = new MailAddress(email);
}
catch (Exception) {
_email = null;
}
}
public EmailAddress(string email, string displayName)
{
try {
_email = new MailAddress(email, displayName);
}
catch (Exception) {
_email = null;
}
}
public EmailAddress(string email, string displayName, Encoding displayNameEncoding)
{
try {
_email = new MailAddress(email, displayName, displayNameEncoding);
}
catch (Exception) {
_email = null;
}
}
public bool IsValid()
{
return _email == null ? false : true;
}
public override string ToString()
{
return this.Address;
}
}
Now you use it just as MailAddress but there is now no exception when the Email address is not valid. Instead you call the IsValid method:
var email = new EmailAddress("user#host.com");
if (email.IsValid()) {
...
}
else {
...
}
Related
this is my post method in apiController
[HttpPost]
public String Post([FromBody]String key)
{
Users ws;
try
{
ws = JsonConvert.DeserializeObject<Users>(key);
// return "success "+ key;
return db.InsertFineInfo(ws);
}
catch (Exception ex)
{
return "ERROR Testing Purposes: " + ex;
}
}
This is part of my model calss.(Users class)there are many attributes but here i have mentioned only few of em with getters and setters
{
private String UserID;
private String UserName;
private String UserHeight;
private String UserWeight;
private String UserBMI;
private String RequiredNeutrition;
public string UserID1
{
get
{
return UserID;
}
set
{
UserID = value;
}
}
i tried to call this post method using postmen .in every attempt i get a null value for key .
this is how i tried the post method with one header parameter application/json
what went wrong ? something wrong with method or the way i try to call it?
OK a couple points...
Firstly the JSON your method would be expecting would look like
{
"key": "your string....."
}
Secondly the code you have supplied is a bit counter intuitive... Why not simply have
[HttpPost]
public String Post([FromBody]Users ws)
{
... // Done ?
}
You need to publish more code for me to be able to give you a correct answer as to what the JSON would look like that would be accepted by the above method.
In Web API when the parameter comes through as null you can be pretty sure that the JSON sent to the method does not match the JSON generated when you serialize the parameter to a JSON string.
You have to model your input as a C# class, and then take that type as an input.
Assuming that you already have a "User" class, with the same properties as the JSON, that you send in the request body:
[HttpPost]
public String Post([FromBody]User user)
{
try
{
return db.InsertFineInfo(user);
}
catch (Exception ex)
{
return "ERROR Testing Purposes: " + ex;
}
}
My code:
public string GetUserId(IRequest request) {
var token = request.QueryString.Get("token");
// what is it? request.User.Identity.Name;
if (string.IsNullOrWhiteSpace(token)) {
return token;
}
else {
return JsonConvert.SerializeObject(new UserAbility().GetUserByToken(token));
}
}
I need to map the connection with the user using a different identifier.
So i want to get the custom token from the QueryString in this method, but GetUserId doesn't trigger in every reqeust.
And i always get the request.User.Identity.Name is string empty?
This article explains what you need to do.
http://www.asp.net/signalr/overview/guide-to-the-api/mapping-users-to-connections#IUserIdProvider
Is it possible to use the IUserIDProvider instead of ConnectionID when working with Groups? I have already found an answer here, but that concerns the SignalR 1.0 version. I wonder, whether things have changed in 2.0.
So far, I was using the conventional
Groups.Add(Context.ConnectionId, "groupName");
However, it was difficult to keep track of the connected users when their connectionID was changed (the client is a Xamarin Android app and somehow, reconnection always resulted in creation of a new ConnectionID). Thus, when the client is connecting, I have added a header:
public async Task<bool> Login(int waitMilis, string name)
{
var cts = new CancellationTokenSource();
try
{
cts.CancelAfter(waitMilis);
_connection.Headers.Add("userName", name);
await _connection.Start();
return true;
}
catch(Exception ex)
{
CallFailure(ex);
return false;
}
}
And on server side, implemented the IUserIdProvider:
public class MyUserProvider : IUserIdProvider
{
public string GetUserId(IRequest request)
{
if (request == null)
throw new ArgumentNullException("request");
else if (request.Headers != null && request.Headers["userName"] != null)
return request.Headers["userName"].ToString();
else return null;
}
}
Now, I would like to do something like
Groups.Add("userName", "groupName");
but the Add method does not have an overload for IUserIdProvider. So, is there a possibility to combine the IUserIdProvider and working with Groups, or am I stuck to creating a ConcurrentDictionary and then calling this?
foreach(User user in group.Users)
{
Clients.User(user.Name).SendMessage(message,
group.LastUpdateIndex
);
}
It ruins the whole beauty and simplicity of the SignalR code :-/
Unfortunately, there isn't currently a method like Groups.Add("userName", "groupName"); in SignalR.
I suggest adding users to their appropriate group(s) in OnConnected:
public class MyHub : Hub
{
public override async Task OnConnected()
{
var userName = MyUserHelper.GetUserId(Context.Request);
foreach (var groupName in GroupManager.GetJoinedGroups(userName))
{
await Groups.Add(Context.ConnectionId, groupName);
}
}
// ...
}
If you need to add an already connected user to a group, then you will likely need to send a message to the user using something like Clients.User(userName).joinGroup(groupName). Each client with userName could then call the appropriate hub method to join groupName.
I'm trying to receive an answer from a WCF method from the client. When I try to execute void methods, they are working fine. For example:
Uri u = new Uri(string.Format(LogIn.ctx.BaseUri + "/CreateRole?name='{0}'",
TextBox1.Text), UriKind.RelativeOrAbsolute);
LogIn.ctx.Execute(u, "GET");
Now I want to call a method which returns a boolean, and this value will be used. Here's the method I want to call and receive its returned value:
[WebGet]
public bool Controler(string role, string user)
{
if (Roles.IsUserInRole(user, role))
{
return true;
}
else
{
return false;
}
}
Instead of LogIn.ctx.Execute(u, "GET"), try this:
IEnumerable<bool> result = LogIn.ctx.Execute<bool>(u);
bool answer = result.Single();
In a custom role provider (inheriting from RoleProvider) in .NET 2.0, the IsUserInRole method has been hard-coded to always return true:
public override bool IsUserInRole(string username, string roleName) { return true; }
In an ASP.NET application configured to use this role provider, the following code returns true (as expected):
Roles.IsUserInRole("any username", "any rolename"); // results in true
However, the following code returns false:
Roles.IsUserInRole("any rolename"); // results in false
Note that User.IsInRole("any rolename") is also returning false.
Is this the expected behavior?
Is it incorrect to assume that the overload that only takes a role name would still be invoking the overridden IsUserInRole?
Update: Note that there doesn't seem to be an override available for the version that takes a single string, which has led to my assumption in #2.
I looked at Roles.IsUserInRole(string rolename) in .net reflector, and it resolves to the following:
public static bool IsUserInRole(string roleName)
{
return IsUserInRole(GetCurrentUserName(), roleName);
}
I would take a look at your current user. Here's why:
private static string GetCurrentUserName()
{
IPrincipal currentUser = GetCurrentUser();
if ((currentUser != null) && (currentUser.Identity != null))
{
return currentUser.Identity.Name;
}
return string.Empty;
}
I would be willing to bet this is returning an empty string because you either don't have a Current User, or its name is an empty string or null.
In the IsUserInRole(string username, string roleName) method, there is the following block of code right near the beginning:
if (username.Length < 1)
{
return false;
}
If your GetCurrentUserName() doesn't return anything meaningful, then it will return false before it calls your overridden method.
Moral to take away from this: Reflector is a great tool :)
Also beware if you have selected cacheRolesInCookie="true" in the RoleManager config. If you have added a new role to the database, it might be looking at the cached version in the cookie.
I had this problem and the solution was to delete the cookie and re-login.
This may help someone - be aware:
If you are using the login control to authenticate - the username entered into the control becomes the HttpContext.Current.User.Identity.Name which is used in the Roles.IsUserInRole(string rolename) and more specifically - the membership's GetUser() method. So if this is the case make sure you override the Authenticate event, validate the user in this method and set the username to a value that your custom membership provider can use.
protected void crtlLoginUserLogin_Authenticate(object sender, AuthenticateEventArgs e)
{
bool blnAuthenticate = false;
string strUserName = crtlLoginUserLogin.UserName;
if (IsValidEmail(strUserName))
{
//if more than one user has email address - must authenticate by username.
MembershipUserCollection users = Membership.FindUsersByEmail(strUserName);
if (users.Count > 1)
{
crtlLoginUserLogin.FailureText = "We are unable to determine which account is registered to that email address. Please enter your Username to login.";
}
else
{
strUserName = Membership.GetUserNameByEmail(strUserName);
blnAuthenticate = Membership.ValidateUser(strUserName, crtlLoginUserLogin.Password);
//setting the userLogin to the correct user name (only on successful authentication)
if (blnAuthenticate)
{
crtlLoginUserLogin.UserName = strUserName;
}
}
}
else
{
blnAuthenticate = Membership.ValidateUser(strUserName, crtlLoginUserLogin.Password);
}
e.Authenticated = blnAuthenticate;
}