Property value returned by DirectorySearcher and SearchResponse are of different type System._comobject and Byte array - asp.net

I am working on a website to manage active directory. I want to check that whether user has permission to change password or not. So I have to find "ntSecurityDescriptor" property value after that I have to cast it into IADsSecurityDescriptor.
Now if I use DirectorySearcher class then property value is of type System._ComObject and easily casted to IADsSecurityDescriptor. But when I use LdapConnection and SearchResponse I get property value of type.
byte[] array which is unale to cast to IADsSecityDescriptor.
I am getting error
Unable to cast System.Byte[] to IADsSecurityDescriptor
Is there some problem with SearchResponse or I have use some kind of casting technique to achieve this? I have some problem to use DirectoryEntry class so I can only use LdapConnction class.

At last I find the answer of my question. This class convert the byte[] to valid security decriptor comobject.
ActiveDs.ADsSecurityUtility secUtility = new ActiveDs.ADsSecurityUtility();
ActiveDs.IADsSecurityDescriptor sd = (IADsSecurityDescriptor)secUtility.ConvertSecurityDescriptor((byte[])attribute[0], (int)ADS_SD_FORMAT_ENUM.ADS_SD_FORMAT_RAW, (int)ADS_SD_FORMAT_ENUM.ADS_SD_FORMAT_IID);

I think you should put your effort in trying to use the DirectoryEntry method.
You will have very hard times trying to manipulate AD objects with LdapConnection.
If you want to continue the Ldap way, after a quick search, I would give a try to the native (this word says it all) autorization functions. There seems to be interesting things in there, like :
ConvertStringSecurityDescriptorToSecurityDescriptor
http://msdn.microsoft.com/en-us/library/windows/desktop/aa376401%28v=vs.85%29.aspx
C# syntax
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("Advapi32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
internal static extern bool ConvertStringSecurityDescriptorToSecurityDescriptor(string StringSecurityDescriptor, uint StringSDRevision, ref IntPtr SecurityDescriptor, IntPtr SecurityDescriptorSize);

Related

Can I cast a string object passed on command line argument to the actual object?

Is it possible to cast a command-line passed string object back to actual object?
I want to do the following, but throwing error can't cast.
Button objPro = (Button) sender;
cProduct cp = (cProduct) objPro.CommandArgument;
If no, then why?
This is what the string holds.
cProduct cpObj = (cProduct)e.Row.DataItem;
Button btnAddProduct = (Button)e.Row.FindControl("btnAddProduct");
if (btnAddProduct != null)
{
btnAddProduct.CommandArgument = cpObj.ToString();
}
You probably can't, because it's a string. It's not a cProduct (whatever that is - consider following .NET naming conventions and naming it Product instead).
Now you could do this if you had a explicit conversion operator in cProduct to create an instance from a string.
You haven't really explained what's in the string, or what's in the type - but if your cProduct type provides a ToString method which contains all the data in a reversible form, then you could easily write a method or a constructor to create the product again:
Product product = new Product(objPro.CommandArgument);
or maybe:
Product product = Product.Parse(objPro.CommandArgument);
You'll have to write that constructor/method, of course.
I would strongly recommend using a constructor or method instead of an operator, just to keep your code clearer - it's very rarely a good idea to write your own conversion operators.
Take a look at CommandArgument on MSDN. The property is a string, when you assign the a value to the property, you aren't casting some complex type to string, you are setting a string value on the property. Can you cast a string back to your object type anyway, regardless of it being a CommandArgument. I doubt it. If the argument is an int you could try int.Parse or similar for other types which have a parse method.

Fastest way to get numerical value of the request's IP Address in ASP.NET

What would be the fastest way to get the numerical format (NOT THE STRING FORMAT) of the client?
string format : 223.255.254.0
numeric format : 3758095872
I can postcompute this by some code like
static public uint IPAddressToLong(string ipAddress)
{
var oIP = IPAddress.Parse(ipAddress);
var byteIP = oIP.GetAddressBytes();
var ip = (uint)byteIP[0] << 24;
ip += (uint)byteIP[1] << 16;
ip += (uint)byteIP[2] << 8;
ip += byteIP[3];
return ip;
}
based on the Request.UserHostAddress string but I was hoping that IIS or ASP.NET precomputes this and it's somewhere hidden in the HttpContext.
Am I wrong?
HttpContext does not seem to be doing any more magic than what you already see: a string value in HttpRequest.UserHostAddress
Some background info:
HttpContext.Current.Request is of type System.Web.HttpRequest which takes a System.Web.HttpWorkerRequestas parameter when instantiated.
The HttpWorkerRequest is an abstract class instantiated by hosting implementations like, in case of IIS, System.Web.Hosting.IIS7WorkerRequest which then implements the abstract method GetRemoteAddress() of HttpWorkerRequest which is internally used by HttpRequest.UserHostAddress.
IIS7HttpWorkerRequest knows that REMOTE_ADDR is the IIS property it needs to read and, after going through a few more layers of abstraction while passing around the request context, it all finally ends in calling MgdGetServerVariableW(IntPtr pHandler, string pszVarName, out IntPtr ppBuffer, out int pcchBufferSize); in webengine.dll which simply writes a string of length pcchBufferSize into ppBuffer containing the same stuff you get from HttpRequest.UserHostAddress.
Since i doubt that there are other parts in the HttpContext that get fed request-sender related information, i'm assuming you'll have to keep doing your own magic for conversion for which there are plenty of ideas in the link i posted in the comments.

DataMember Emit Default Value

I have a .Net Web Service function that can accept one string.
That function will then serialize that string to JSON, but I only want to serialize it if it's value is not "".
I found these instructions:
http://msdn.microsoft.com/en-us/library/aa347792.aspx
[DataContract]
public class MyClass
{
[DataMember (EmitDefaultValue=false)]
public string myValue = ""
}
Unfortunatelly I can not hide the myValue from the serialization because "" is not the .Net default value for a string (how dumb is that!)
One of two option ocurred
On the web service have some kind of attribute that sets the "" to null
Have some condition on the class
I would prefer the 1st because it makes the code cleaner but an opinion would be great.
Thanks
You can explicitly set what the default value is (for the purposes of serialization) using the DefaultValueAttribute class:
[DataContract]
public class MyClass
{
[DataMember (EmitDefaultValue=false)]
[DefaultValue("")]
public string myValue = ""
}
I think you have at least a couple of options here. It's extra work but worth it.
You can encapsulate the string in a reference type. Since reference types are null if not present, that lets you know right away if a string was present or not (because the encapsulating reference type would be either non-null or null, if the string is non-empty or not.)
A final option you have is to add an extra complementary variable (perhaps a boolean) that is set on OnDeserializing/OnDeserialized/OnSerializing/OnSerialized and use this to track whether or not something was actually present on the wire. You might, for example, set this complementary variable to true only when you're actually serializing out a non-empty string and similarly

Programmatically get a Type's Alias in .NET

Is it possible to determine an object type's alias(es) through reflection? Given the following example where myObject is of type System.Int32 -- e.g
Type t = myObject.GetType();
t.Name will be Int32. However, I would like to identify the possibile alias(es), if any, of the objects in question, so that I could resolve the type name of int in addition to Int32
I'm not looking to spend a huge amount of time on this. If there isn't an extreamely simple, built in solution, I'll just map the values myself. =)
Not directly with reflection, there is not. The "type name" (as you are calling it) "int" is not a type name at all, but a language keyword.
You could, of course, use a dictionary to store the look ups from type names to the shorter convenience forms. But there is nothing in the reflection API's that will do that for you.
You can get language specific type alias by using CodeDom classes
var cs = new CSharpCodeProvider();
var vb = new VBCodeProvider();
var type = typeof (int);
Console.WriteLine("Type Name: {0}", type.Name); // Int32
Console.WriteLine("C# Type Name: {0}", cs.GetTypeOutput(new CodeTypeReference(type))); // int
Console.WriteLine("VB Type Name: {0}", vb.GetTypeOutput(new CodeTypeReference(type))); // Integer
The aliases appear to be compile-time only. Notice how they don't apply outside of a given source file. They are simply conveniences, nothing more.

How do I create a shallow copy of an object so that it may be serialize and sent via a web method call?

I would like to serialize the properties of the HttpBrowserCapibilities object so that it may be returned via a web method call. Currently the object cannot be serialized:
Cannot serialize member System.Web.Configuration.HttpCapabilitiesBase.Capabilities of type System.Collections.IDictionary, because it implements IDictionary.
...which is understandable. However, I would like to simply copy out the properties and their values to a hierarchy, i.e.
<HttpBrowserCapabilities>
<IsMobile>true</IsMobile>
</HttpBrowserCapabilities>
I'm starting to think I would need to use reflection to copy this object, but I haven't reached a conclusion. Does anyone have any suggestions to keep this simple?
Thanks,
George
Originally I posted an answer using XmlDocument, but I glossed over some of the web method stuff and didn't realize you were really trying to map a DTO.
Reflection sounds complicated but it really isn't. The following snippet will do what you want:
public static void Populate(object dest, IDictionary dictionary)
{
Type t = dest.GetType();
foreach (object key in dictionary)
{
PropertyInfo prop = t.GetProperty(key.ToString(),
BindingFlags.Instance | BindingFlags.Public);
if ((prop != null) && prop.CanWrite)
{
object value = dictionary[key];
prop.SetValue(dest, value, null);
}
}
}
Then invoke this as:
BrowserCapsDto dto = new BrowserCapsDto();
Populate(dto, Capabilities); // Capabilities is the real BrowserCaps
It's pretty easy because you already have an IDictionary and thus you already know all of the possible names you can map; you don't actually need to use any reflection on the source, just the destination.

Resources