I want to implement a function which connects to AD via Ldap.
My code:
public bool TryConnect(string server, string userName, string password)
{
try
{
var credentials = new NetworkCredential(#"test\administrator123", #"P2ssw0rd");
var ldapidentifier = new LdapDirectoryIdentifier("Test");
using (var ldapconn = new LdapConnection(ldapidentifier, credentials))
{
ldapconn.AuthType = AuthType.Basic;
var request = new SearchRequest("dc=test, dc=local", "(objectClass=user)", System.DirectoryServices.Protocols.SearchScope.Subtree, null);
var response = (SearchResponse)ldapconn.SendRequest(request);
}
}
catch (Exception)
{
return false;
}
return true;
}
This is working, but I don't like it !
Is there some cleaner way how to test connection without try/catch and without some dummy search request?
Instead of performing a search, you could call the Bind() method to test basic connectivity like so:
ldapconn.Bind();
However I don't know a way to test this without try/catch.
Related
I would like to build an app that i'll use for myself so i'm targeting the simple authentification through Token.
I had my token from Discog and i know it works because i tried it in a third party app.
I'm using DiscogClient which seems to be the most popular client.
I'm following the Sample usage in the following way :
var tokenInformation = new TokenAuthenticationInformation("My token"); // i'm using my real token of course
//Create discogs client using the authentication
var discogsClient = new DiscogsClient.DiscogsClient(tokenInformation);
var discogsSearch = new DiscogsSearch()
{
artist = "Michael Jackson"
};
//Retrieve observable result from search
var observable = discogsClient.Search(discogsSearch);
I dont have any exception when i run that code, but if i look at the observable var in debug mode, there is no result whatsoever.
I'm lost and am seeking help.
Thanks in advance
ok so this is how i made it work, sound simple but i'm not used to thread programming.
var tokenInformation = new TokenAuthenticationInformation("My token"); // i'm using my real token of course
{
//Create discogs client using the authentication
var discogsClient = new DiscogsClient.DiscogsClient(tokenInformation);
var discogsSearch = new DiscogsSearch()
{
artist = "Michael Jackson"
};
await SearchDis(discogsClient, discogsSearch);
}
then the function
private async static Task SearchDis (DiscogsClient.DiscogsClient dc, DiscogsSearch ds)
{
var res = await dc.SearchAsync (ds);
}
Can someone help me how to make the call to the method SendSms(textMessageItems) asynchronous? What is the best method/practice? I am presuming that Task.Run Async-Await can be used here since I am using .Net4.5 using MVC4 WebApi. But I would like to hear from the experts as I am new to this. I am using this code in my web Server which is in IIS7 and this method could take sometime to process and so would like to process it asynchronously so that the response can return right away to the caller.
Also since I am calling the SendSms inside a for loop would it cause any issue? Do you think I should pass it as a collection List and then process? Please advise.
using Twilio.Mvc;
using Twilio.TwiML.Mvc;
using Twilio.TwiML;
public class SmsController : ApiController
{
[HttpPost]
public HttpResponseMessage Post([FromBody]SmsRequest smsReq)
{
var response = new Twilio.TwiML.TwilioResponse();
//validation checks..
try
{
if ((txtMessageResponse != null) && (txtMessageResponse.SmsMessageInfo.Count > 0))
{
_smsStagingList = txtMessageResponse.SmsMessageInfo;
foreach (TextMessageStaging prepareTextMessageResponse in _smsStagingList)
{
smsDTO textMessageItems = new smsDTO();
textMessageItems.PhoneNumber = prepareTextMessageResponse.PhoneNumber;
textMessageItems.SmsMessage = prepareTextMessageResponse.SmsMessageBody;
isTxtMessageSent = SendSms(textMessageItems);
//If the messages were sent then no need to set the flag to be updated
if (isTxtMessageSent)
{
txtMessageStatusToBeUpdated = false;
}
}
return Request.CreateResponse(HttpStatusCode.OK, twilioResponse.Element);
}
else
{
//send error response
}
catch (Exception msgProcessingError)
{
//send error response again as processing error
}
finally
{
//set the outbound flag in the table
}
}
private bool SendSms(smsDTO textMessageItems)
{
bool isTxtMessageSent = false;
PushMessageRequest txtMessageRequest = new PushMessageRequest();
PushMessageResponse txtMessageResponse = null;
txtMessageRequest.SmsMessageInfo = new SendTextMessage(); //instantiate the dto
txtMessageRequest.SmsMessageInfo.ToPhone = textMessageItems.PhoneNumber;
txtMessageRequest.SmsMessageInfo.TextMessage = textMessageItems.SmsMessage;
try
{
using (ITextService textService = ObjectFactory.SendSmsMessage())
{
txtMessageResponse = textService.SendSmsMessage(txtMessageRequest);
}
isTxtMessageSent = txtMessageResponse.IsSuccessful;
}
catch (Exception ex)
{
isTxtMessageSent = false;
}
return isTxtMessageSent;
}
I recommend that you not use Task.Run. AFAIK, Twilio does not have an async API, so you should ask them about that. You could of course write your own, e.g., based on HttpClient.
would like to process it asynchronously so that the response can return right away to the caller
Please note that async does not change the HTTP protocol, as described on my blog. It is possible, but extremely dangerous, to return a response from ASP.NET while the request has not finished processing (also a link to my blog).
I've build a simple intranet application using ASP.NET MVC4 that allows users inside network to view some resources. Application is build mostly in ExtJS and WebAPI controllers.
My authorization is based on Active Directory.
Debugging my code I noticed that I'm doing AD calls multiple times.
Here is my AD helper class:
public class AD
{
public static string CurrentUser = "";
public static string GetCurrentUserLogin()
{
return HttpContext.Current.User.Identity.Name.Split('\\')[1];
}
public static Employee GetCurrentUser()
{
var login = CurrentUser == "" ? GetCurrentUserLogin() : CurrentUser ;
return GetUser(login);
}
public static Employee GetCurrentUser(string login)
{
return GetUser(login);
}
public static Employee GetUser(Guid guid)
{
using (var entry = new DirectoryEntry("LDAP://wawa.firma.pl/OU=IT,DC=wawa,DC=firma,DC=pl", #"AD_client", "xyzabc"))
{
using (var searcher = new DirectorySearcher(entry))
{
byte[] bytes = guid.ToByteArray();
var sb = new StringBuilder();
foreach (byte b in bytes)
{
sb.Append(string.Format(#"\{0}", b.ToString("X2")));
}
searcher.Filter = String.Format("(&(objectClass=User)(objectCategory=Person)(objectguid={0}))", sb);
searcher.PropertiesToLoad.Add("description");
searcher.PropertiesToLoad.Add("objectguid");
searcher.PropertiesToLoad.Add("SN");
searcher.PropertiesToLoad.Add("givenName");
searcher.PropertiesToLoad.Add("name");
searcher.PropertiesToLoad.Add("manager");
searcher.PropertiesToLoad.Add("mail");
searcher.PropertiesToLoad.Add("sAMAccountName");
searcher.PropertiesToLoad.Add("telephoneNumber");
searcher.PropertiesToLoad.Add("directReports");
searcher.SizeLimit = 1;
searcher.SearchScope = SearchScope.Subtree;
try
{
SearchResult result = searcher.FindOne();
if (result == null) return null;
var emp = ParseSearchResult(result);
emp.fullAccess = true;
return emp;
}
catch (Exception)
{
return null;
}
}
}
}
}
This works fine, but every time I must get current user id and I do call like this:
var user_id = AD.GetCurrentUser().Id;
My problem is that every time I request some property for user that is stored in AD i must do new AD call.
Ideally I would like to do simple call once (for current user) and store it, then every time I need something I will get it from local object.
I read some articles about session in WebAPI controllers, for example: http://stick2basic.wordpress.com/2013/04/18/how-to-access-session-in-web-api-controller-in-mvc4/, but I found also greate example of using Cache: https://github.com/filipw/AspNetWebApi-OutputCache
But Session is per User and Cache per Application.
What would be best way of storing ActiveDirectory results per User? How should I modify my AD class to hold those variables.
The easiest way would be to store result in session as so:
public static Employee GetUser(Guid guid)
{
var e = HttpContext.Current.Session[guid.ToString()] as Employee;
if (e == null)
{
//get user from AD
//store in session
}
return e;
}
This way I'll be able to query AD only once, but I won't be able to requery every n-minutes (cache has timeout).
How can I make this easier/better? Are there other ways to do this?
You need some memory cache. Have a look at: MemoryCache Class
Store the DirectoryEntry object in the cache with the path as key.
I have a piece of code where I am connecting via Exchange Web Services, and I have the message ID. I need to change the subject of this email to the string passed into my method for successful processing later in my workflow. However, I am a bit confused as to how to use the exchange web services classes, my code is below:
public bool SetEmailCorrectSubject(string msgID, string subject)
{
bool bSuccess = true;
if (String.IsNullOrEmpty(msgID))
{
return false;
}
try
{
ItemIdType messageId = new ItemIdType();
messageId.Id = msgID;
ItemChangeDescriptionType desc = new ItemChangeDescriptionType();
// Not sure how to set this up
ItemChangeType itemChange = new ItemChangeType();
itemChange.Item = messageId;
UpdateItemType updateItem = new UpdateItemType();
}
catch (Exception e)
{
_logger.Error("error with resending email with title", e);
return false;
}
return bSuccess;
}
From what I understand, the UpdateItemType class is the way to go, but I'm not clear on how to tell it that I want to change the email subject to the subject parameter.
Any ideas? Is using UpdateItemType even the best way to do this?
Instead of EWS you should use the EWS Managed API as it's more simple to use:
EWS Managed API - Download: http://www.microsoft.com/download/en/details.aspx?id=13480
EWS Managed API - SDK: http://msdn.microsoft.com/en-us/library/dd633710(v=exchg.80).aspx
Apart from that, you don't use the ItemChangeType and UpdaetItemType to modify items. Use the Item.Bind() method to bind to the item, change the subject and update it:
var service = new ExchangeService(ExchangeVersion.Exchange2010_SP1)
{
UseDefaultCredentials = true,
Url = new Uri("https://casserver/ews/exchange.asmx")
};
Item item = Item.Bind(service, new Itemid(msgid));
item.Subject = "test";
item.Update(ConflictResolutionMode.AutoResolve);
Btw, are you sure you have the ItemId? Or do you have an RFC 822 Message-Id? Those two are different.
Currently, I make a GetObjectMetaDataRequest, if the GetObjectMetaDataResponse throw an exception means the object doesn't exist. Is there a better way to check whether the file exists without downloading the file.
you can use S3FileInfo class and Exists method of this class it will hep you to check if file exists without download the file .see the example below I used the AWSSDK 3.1.6 .net(3.5) :
public static bool ExistsFile()
{
BasicAWSCredentials basicCredentials = new BasicAWSCredentials("my access key", "my secretkey");
AmazonS3Config configurationClient = new AmazonS3Config();
configurationClient.RegionEndpoint = RegionEndpoint.EUCentral1;
try
{
using (AmazonS3Client clientConnection = new AmazonS3Client(basicCredentials, configurationClient))
{
S3FileInfo file = new S3FileInfo(clientConnection, "mybucket", "FolderNameUniTest680/FileNameUnitTest680");
return file.Exists;//if the file exists return true, in other case false
}
}
catch(Exception ex)
{
return false;
}
}
If you are in a similar situation as myself and are using .Net Core and don't have access to Amazon.S3.IO (and S3FileInfo method), you can do the following using asynchronous GetObjectMetadataRequest method:
static private AmazonS3Client s3Client = new AmazonS3Client();
public static async Task<bool> FileExistsS3Async(string _bucket, string _key)
{
GetObjectMetadataRequest request = new GetObjectMetadataRequest()
{
BucketName = _bucket,
Key = _key
};
try
{
await s3Client.GetObjectMetadataAsync(request);
return true;
}
catch (AmazonS3Exception exception)
{
return false;
}
}
This function has worked for me when calling within a Unity game. You can also call the above function synchronously using the following:
bool exists = Task.Run(()=>FileExistsS3Async(_bucket, _key)).Result;
Try this solution, it works for me.
AmazonS3Client client = new AmazonS3Client(accessKey, secretKey, regionEndpoint);
S3FileInfo s3FileInfo = new S3FileInfo(client, bucketName, fileName);
return s3FileInfo.Exists;
There is no ListObjectRequest, but instead a ListObjectsRequest where you cannot specify the Key. You then have to go through all the objects to find the one you want. I am currently looking in to it since I seem to get time out errors whilst downloading the file. (If anyone has some idea how to solve that feel free to comment).
You could instead try the List Parts Request if you happen to know the upload id.
Other than that I have no idea. Would like to have a chat with the person who wrote the S3 api...
You're probably going to have to use the REST API yourself, as the method suggested, internally just does exactly the same thing (try...catch on the request)
You can use this code to check whether an object exist in S3 or not:
public class S3CheckFileExists
{
private readonly IAmazonS3 amazonS3;
public S3CheckFileExists(IAmazonS3 amazonS3)
{
this.amazonS3 = amazonS3;
}
public async Task<bool> S3ObjectExists(string bucketName, string keyLocation)
{
var listS3Objects = await this.amazonS3.ListObjectsV2Async(new ListObjectsV2Request
{
BucketName = bucketName,
Prefix = keyLocation, // eg myfolder/myimage.jpg (no / at start)
MaxKeys = 1
});
if (listS3Objects.S3Objects.Any() == false || listS3Objects.S3Objects.All(x => x.Key != keyLocation))
{
// S3 object doesn't exist
return false;
}
// S3 object exists
return true;
}
}
You'll need to register IAmazonS3 in your IoC (aka services) container though:
services.AddAWSService<IAmazonS3>();
Yes.
You can use a ListObjectsRequest. Use the Marker property, and retrieve only 1 element.