Should I Be Using Protocols for these Models? - swift-protocols

I am working with the Dribbble API, and there are three models that I am currently using:
User
Team
Shot
A Shot is something that a User or Team uploads to their respective portfolio to be shown off. This can be an image or an animation. A User can belong to multiple Teams, while a Team can have multiple Users.
The three models each have many properties, which I have provided below.
User takes the following structure:
/// Encapsulates information about a Dribbble User.
public struct User {
// MARK: - Properties
/// The identifier of the User.
public var identifier: Int?
/// The name of the User.
public var name: String?
/// The username of the User.
public var username: String?
/// The `URL` for the User's Dribbble page.
public var htmlURL: URL?
/// The `URL` for the User's avatar image.
public var avatarURL: URL?
/// The biography for the User.
public var biography: String?
/// The location for the User.
public var location: String?
/// The `URL` for the User's website.
public var websiteURL: URL?
/// The `URL` for the User's Twitter profile.
public var twitterURL: URL?
/// The number of Buckets for the User.
public var bucketsCount: Int?
/// The number of Comments the User has received.
public var commentsReceivedCount: Int?
/// The number of followers for the User.
public var followersCount: Int?
/// The number of followings for the User.
public var followingsCount: Int?
/// The number of Likes for the User.
public var likesCount: Int?
/// The number of Likes received for the User.
public var likesReceivedCount: Int?
/// The number of projects for the User.
public var projectsCount: Int?
/// The number of Rebounds received for the User.
public var reboundsReceivedCount: Int?
/// The number of Shots for the User.
public var shotsCount: Int?
/// The number of Teams that the User belongs to.
public var teamsCount: Int?
/// Whether the User is authorized to upload Shots.
public var canUploadShot: Bool?
/// The type of User.
public var type: String?
/// Whether the User has Pro status.
public var isPro: Bool?
/// The `URL` for the User's Buckets.
public var bucketsURL: URL?
/// The `URL` for the User's followers.
public var followersURL: URL?
/// The `URL` for the User's followings.
public var followingURL: URL?
/// The `URL` for the User's Likes.
public var likesURL: URL?
/// The `URL` for the User's Projects.
public var projectsURL: URL?
/// The `URL` for the User's Shots.
public var shotsURL: URL?
/// The `URL` for the Teams that the User belongs to.
public var teamsURL: URL?
/// The `Date` that the User was created.
public var createdAt: Date?
/// The `Date` that the User was last updated.
public var updatedAt: Date?
}
Team takes the following structure:
/// Encapsulates information about a Dribbble Team.
public struct Team {
// MARK: - Properties
/// The identifier of the Team.
public var identifier: Int?
/// The name of the Team.
public var name: String?
/// The username of the Team.
public var username: String?
/// the `URL` for the Team's Dribbble page.
public var htmlURL: URL?
/// The `URL` for the Team's avatar image.
public var avatarURL: URL?
/// The biography for the Team.
public var biography: String?
/// The location for the Team.
public var location: String?
/// The `URL` for the Team's website.
public var websiteURL: URL?
/// The `URL` for the Team's Twitter profile.
public var twitterURL: URL?
/// The number of Buckets for the Team.
public var bucketsCount: Int?
/// The number of Comments the Team has received.
public var commentsReceivedCount: Int?
/// The number of followers for the Team.
public var followersCount: Int?
/// The number of followings for the Team.
public var followingsCount: Int?
/// The number of Likes for the Team.
public var likesCount: Int?
/// The number of Likes received for the Team.
public var likesReceivedCount: Int?
/// The number of projects for the Team.
public var projectsCount: Int?
/// The number of Rebounds received for the Team.
public var reboundsReceivedCount: Int?
/// The number of Shots for the Team.
public var shotsCount: Int?
/// Whether the Team is authorized to upload Shots.
public var canUploadShot: Bool?
/// The type of Team.
public var type: String?
/// Whether the Team has Pro status.
public var isPro: Bool?
/// The `URL` for the Team's Buckets.
public var bucketsURL: URL?
/// The `URL` for the Team's followers.
public var followersURL: URL?
/// The `URL` for the Team's followings.
public var followingURL: URL?
/// The `URL` for the Team's Likes.
public var likesURL: URL?
/// The `URL` for the Team's Projects.
public var projectsURL: URL?
/// The `URL` for the Team's Shots.
public var shotsURL: URL?
/// The `Date` that the Team was created.
public var createdAt: Date?
/// The `Date` that the Team was last updated.
public var updatedAt: Date?
/// The number of members for the Team.
public var membersCount: Int?
/// The `URL` for the members of the Team.
public var membersURL: URL?
/// The `URL` for the Team Shots.
public var teamShotsURL: URL?
}
Shot takes the following structure:
/// Encapsulates information about a Dribbble Shot.
public struct Shot {
// MARK: - Properties
/// The identifier of the Shot.
public var identifier: Int?
/// The title of the Shot.
public var title: String?
/// The description of the Shot.
public var description: String?
/// The size of the Shot.
public var size: CGSize?
/// The `URL` for the Shot's high-definition image.
public var highDefinitionImageURL: URL?
/// The `URL` for the Shot's normal image.
public var normalImageURL: URL?
/// The `URL` for the Shot's teaser image.
public var teaserImageURL: URL?
/// The number of views for the Shot.
public var viewsCount: Int?
/// The number of likes for the Shot.
public var likesCount: Int?
/// The number of comments for the Shot.
public var commentsCount: Int?
/// The number of attachments for the Shot.
public var attachmentsCount: Int?
/// The number of Rebounds for the Shot.
public var reboundsCount: Int?
/// The number of Buckets for the Shot.
public var bucketsCount: Int?
/// The `Date` that the Shot was created.
public var createdAt: Date?
/// The `Date` that the Shot was last updated.
public var updatedAt: Date?
/// The `URL` for the Shot's Dribbble page.
public var htmlURL: URL?
/// The `URL` for the Shot's attachments.
public var attachmentsURL: URL?
/// The `URL` for the Shot's Buckets.
public var bucketsURL: URL?
/// The `URL` for the Shot's comments.
public var commentsURL: URL?
/// The `URL` for the Shot's Likes.
public var likesURL: URL?
/// The `URL` for the Shot's Projects.
public var projectsURL: URL?
/// The `URL` for the Shot's Rebounds.
public var reboundsURL: URL?
/// Whether the Shot is animated.
public var isAnimated: Bool?
/// The tags associated with the Shot.
public var tags: Array<String>?
/// The `User` that the Shot belongs to.
public var user: User?
/// The `team` that she Shot belongs to.
public var team: Team?
}
User and Team have many duplicated properties, while Shot has a few that User and Team have. If I take the protocol route for these models, there will be many protocol implementations.
In my case, I have no reason to have an Array of Identifiable types or WebsiteURL types, or any other type that conforms to a protocol for the duplicated properties. I will have an Array of Shots, which belong to either Users or Teams. I will also have Arrays for Users and Arrays for Teams.
Should I implement protocols for the duplicated properties and have User, Team, and Shot conform to them, or would this lead to protocol hell for no apparent benefit other than being so-called "Swifty"?

So what about using inheritance like this,
Common parent takes the properties Shot, User and Team have and Parent for user and team just take the properties only user and team have
Common parent
|
-----------------------------------------------
| |
Parent for user and team |
| |
|-----------| |
User Team Shot

Related

SignalR MessagePack Polymorphism

I am implementing a system based on SignalR that will be pushing client events, for message serialization I would want to use MessagePack. When trying to implement the messaging I have run into a problem where SignalR fails to deserialize the messages on the client.
The messages are polymorphic and described with Union attributes, the standard MessagePack Serializer have no problem serializing and deserializing the messages BUT in case of Signal R it fails with error.
The error reported is System.InvalidOperationException: Invalid Union data was detected.
On the client serialization only works when using the actual class, if I try to use the interface or base class then the error appears.
Classes
[DataContract()]
[MessagePackObject()]
[Union(0,typeof(EntityChangeEventMessage))]
public abstract class EntityEventMessage : IEntityEventMessage
{
}
[DataContract()]
[MessagePackObject()]
public class EntityChangeEventMessage : EntityEventMessage
{
#region PROPERTIES
/// <summary>
/// Gets entity id.
/// </summary>
[DataMember(Order = 1)]
[Key(1)]
public int EntityId
{
get; set;
}
/// <summary>
/// Gets event type.
/// </summary>
/// <remarks>
/// This value identifies database operation such as create,delete,update etc.
/// </remarks>
[DataMember(Order = 2)]
[Key(2)]
public int EventType
{
get; set;
}
/// <summary>
/// Gets entity type name.
/// </summary>
[DataMember(Order = 3)]
[Key(3)]
public string EntityType
{
get; set;
}
#endregion
}
[Union(0,typeof(EntityChangeEventMessage))]
public interface IEntityEventMessage
{
}
So this works
connection.On("EntityEvent", (EntityChangeEventMessage d)
This dont work
connection.On("EntityEvent", (IEntityEventMessaged)
So in general it looks like the problem should be in the Microsoft.AspNetCore.SignalR.Protocols.MessagePack library ?
Anyone have implemented such functionality with success ?
Currently SignalR does not support polymorphism with MessagePack, more info here.

Signin Cards for bot in Teams

Can anyone tell Where can I get a JSON for Microsoft Sigin card for Teams bot and how to view it in a visualizer and can it be used to mask the password.
This is the OauthCard.cs file:
// <auto-generated>
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for
// license information.
//
// Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is
// regenerated.
// </auto-generated>
namespace Microsoft.Bot.Schema
{
using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
/// <summary>
/// A card representing a request to perform a sign in via OAuth
/// </summary>
public partial class OAuthCard
{
/// <summary>
/// Initializes a new instance of the OAuthCard class.
/// </summary>
public OAuthCard()
{
CustomInit();
}
/// <summary>
/// Initializes a new instance of the OAuthCard class.
/// </summary>
/// <param name="text">Text for signin request</param>
/// <param name="connectionName">The name of the registered
/// connection</param>
/// <param name="buttons">Action to use to perform signin</param>
public OAuthCard(string text = default(string), string connectionName = default(string), IList<CardAction> buttons = default(IList<CardAction>))
{
Text = text;
ConnectionName = connectionName;
Buttons = buttons;
CustomInit();
}
/// <summary>
/// An initialization method that performs custom operations like setting defaults
/// </summary>
partial void CustomInit();
/// <summary>
/// Gets or sets text for signin request
/// </summary>
[JsonProperty(PropertyName = "text")]
public string Text { get; set; }
/// <summary>
/// Gets or sets the name of the registered connection
/// </summary>
[JsonProperty(PropertyName = "connectionName")]
public string ConnectionName { get; set; }
/// <summary>
/// Gets or sets action to use to perform signin
/// </summary>
[JsonProperty(PropertyName = "buttons")]
public IList<CardAction> Buttons { get; set; }
}
}
It can be found here. That being said, AFAIK, there is no visualizer for it, it's not in JSON, and there's nothing there to mask.
You can create a Sign In card in c#
SigninCard signincard = new SigninCard()
{
Text = "Click here to sign in",
Buttons = new List<CardAction>() {
new CardAction()
{
Title = "Authentication Required",
Type = ActionTypes.OpenUrl,
Value = $"{authenticationUrl}?{encodedCookie}"
}
}
};
Please give a try.

Doing a Join Query In ASP.NET MVC 3 using Sharp Lite Architecture

I'll use the mystore sharp lite architecture example. You can download the solution here:
https://github.com/codai/Sharp-Lite
So there are two entities in question. Products. And ProductCategories.
Products looks like this:
public class Product : Entity
{
public Product() {
Categories = new List<ProductCategory>();
}
[DomainSignature]
[Required(ErrorMessage = "Name must be provided")]
[StringLength(255, ErrorMessage = "Name must be 255 characters or fewer")]
public virtual string Name { get; set; }
/// <summary>
/// Money is a component, not a separate entity; i.e., the Products table will have column
/// for the amount
/// </summary>
[DataType("Money")]
public virtual Money Price { get; set; }
/// <summary>
/// many-to-many between Product and ProductCategory
/// </summary>
[Display(Name="Product Categories")]
public virtual IList<ProductCategory> Categories { get; protected set; }
}
Notice it has the ProductCategories List in it. So it does have a list of ProductCategories that applies to it.
And here is ProductCategory:
public class ProductCategory : Entity
{
public ProductCategory() {
Children = new List<ProductCategory>();
Products = new List<Product>();
}
[DomainSignature]
[Required(ErrorMessage="Name must be provided")]
[StringLength(255, ErrorMessage="Name must be 255 characters or fewer")]
public virtual string Name { get; set; }
/// <summary>
/// many-to-one from child ProductCategory to parent ProductCategory
/// </summary>
[Display(Name="Parent Category")]
public virtual ProductCategory Parent { get; set; }
/// <summary>
/// many-to-many between ProductCategory and Product
/// </summary>
public virtual IList<Product> Products { get; protected set; }
/// <summary>
/// one-to-many from parent ProductCategory to children ProductCategory
/// </summary>
public virtual IList<ProductCategory> Children { get; protected set; }
}
I understand queries enough that I have made simple ones with where statements. For example this is the query I used in another program to search for the first name of a customer:
public static IQueryable<Customer> GetByFirstName(this IQueryable<Customer> customers, string name)
{
name = name.ToUpper();
return
customers.Where(c => c.BillingAddress.FirstName.ToUpper().Contains(name));
}
But I don't quite understand joins yet. Can someone show me the light?
First of all, if you don't understand how to make a Join, you should probably consult some docs on it, but keep in mind, that this has very little (if nothing) to do with Sharp Lite.
The basic idea behind Sharp Lite's repsitories is to use the power of IQueryable in order to depend less on the underlying data access (NH or EF which are the most populars), so you should basically learn how joins work on NH (if you are using NH) and start working using that. Also, try to put up a better example with a more complex structure so you can really do some joins.
If you need a jumpstart on SharpLite, make sure to read the post on why Sharp lite exists and the other explaining how it's built. Also, I made one myself to get people started with the demo project.
Hope I can help!

RemoteAttribute validator does not fire server-side

It appears that the RemoteAttribute validator introduced in ASP.NET MVC 3 does not validate on the server-side, only via JavaScript. If you turn off JS in your browser, you will find that on model binding, the validation controller action (that you specified when decorating a model property with the RemoteAttribute) will not be hit. In fact, if you inspect the source code for the RemoteAttribute, you will find the IsValid methods just returns true in all cases.
This seems to be quite an omission - I think most people would assume that the RemoteAttribute would work like all the other built-in validators and validate on both client-side and server-side. Instead, you must manually call your remote validation logic in your controller action.
Are people aware of this and has anyone tried to address it?
I have subclassed RemoteAttribute and overridden the IsValid method where I have access to RouteData, RouteName and Routes as well as a GetUrl method that returns the action URL. I was thinking about using reflection to call the action and get the result so I can see if it is valid or not, but are there any built-in methods that I can use without resorting to reflection?
Maybe its not the best code. If you have some recommendations please let me know.
Developed #MVC4
Model property with custom attribute
[CustomRemote("ValidateIP", "Validation", ErrorMessage = "Input is not a valid IP")]
Subclassed RemoteAttribute
/// <summary>
/// Custom Remote Attribute for Client an Server validation.
/// </summary>
public class CustomRemoteAttribute : RemoteAttribute
{
/// <summary>
/// List of all Controllers on MVC Application
/// </summary>
/// <returns></returns>
private static List<Type> GetControllerList()
{
return Assembly.GetCallingAssembly().GetTypes().Where(type => type.IsSubclassOf(typeof(Controller))).ToList();
}
/// <summary>
/// Constructor of base class.
/// </summary>
protected CustomRemoteAttribute()
{
}
/// <summary>
/// Constructor of base class.
/// </summary>
public CustomRemoteAttribute(string routeName)
: base(routeName)
{
}
/// <summary>
/// Constructor of base class.
/// </summary>
public CustomRemoteAttribute(string action, string controller)
: base(action, controller)
{
}
/// <summary>
/// Constructor of base class.
/// </summary>
public CustomRemoteAttribute(string action, string controller, string areaName)
: base(action, controller, areaName)
{
}
/// <summary>
/// Overridden IsValid function
/// </summary>
/// <param name="value"></param>
/// <param name="validationContext"></param>
/// <returns></returns>
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// Find the controller passed in constructor
var controller = GetControllerList().FirstOrDefault(x => x.Name == string.Format("{0}Controller", this.RouteData["controller"]));
if (controller == null)
{
// Default behavior of IsValid when no controller is found.
return ValidationResult.Success;
}
// Find the Method passed in constructor
var mi = controller.GetMethod(this.RouteData["action"].ToString());
if (mi == null)
{
// Default behavior of IsValid when action not found
return ValidationResult.Success;
}
// Create instance of the controller to be able to call non static validation method
var instance = Activator.CreateInstance(controller);
// invoke the method on the controller with value
var result = (JsonResult)mi.Invoke(instance, new object[] { value });
// Return success or the error message string from CustomRemoteAttribute
return (bool) result.Data ? ValidationResult.Success : new ValidationResult(base.ErrorMessageString);
}
}
Validation Controller Code
/// <summary>
/// Controller for Client and Server validation
/// <remarks>disable OutputCache</remarks>
/// </summary>
[OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
public class ValidationController : Controller
{
/// <summary>
/// !!!!!!!!!!!!!!!!!! Needed for instance creation in custom attribute !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/// </summary>
public ValidationController()
{
}
/// <summary>
/// IP regex pattern of my choice
/// </summary>
const string IpPattern = #"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";
/// <summary>
/// MAC regex pattern of my choice
/// </summary>
const string MacPattern = "^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$";
/// <summary>
/// Validate IP
/// </summary>
/// <param name="ip">IP param is only submited on Serverside validation!!!</param>
/// <returns>Validation Result</returns>
public JsonResult ValidateIP(string ip)
{
// Check if ip and httpcontext is null to dodge NullReferenceException on Server side validation
if (string.IsNullOrEmpty(ip) && HttpContext == null)
{
return Json(false, JsonRequestBehavior.AllowGet);
}
/* Use IP on Serverside validation
* Use Querystring Param 0 to get IP from Client side vaildation without the need for the correct Id of input control */
string checkip = string.IsNullOrEmpty(ip) ? HttpContext.Request.QueryString[0] : ip;
if (string.IsNullOrEmpty(checkip))
{
return new JsonResult { Data = true, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
return new JsonResult
{
Data = Regex.IsMatch(checkip, IpPattern),
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
This is the intended behavior of remote validation. There is no way to know what the implementation of IsValid would be so it simply returns true. If you want server side validation for the RemoteAttribute you should override IsValid just like you have done.
Remote validator often with an additional field. Here's the implementation for this case.
/// <summary>
/// Remote Attribute for Client an Server validation.
/// </summary>
public class RemoteWithServerSideAttribute : RemoteAttribute
{
/// <summary>
/// List of all Controllers on MVC Application
/// </summary>
/// <returns></returns>
private static IEnumerable<Type> GetControllerList()
{
return Assembly.GetCallingAssembly().GetTypes().Where( type => type.IsSubclassOf( typeof( Controller ) ) ).ToList();
}
/// <summary>
/// Constructor of base class.
/// </summary>
protected RemoteWithServerSideAttribute() {}
/// <summary>
/// Constructor of base class.
/// </summary>
public RemoteWithServerSideAttribute( string routeName ) : base( routeName ) {}
/// <summary>
/// Constructor of base class.
/// </summary>
public RemoteWithServerSideAttribute( string action, string controller ) : base( action, controller ){}
/// <summary>
/// Constructor of base class.
/// </summary>
public RemoteWithServerSideAttribute( string action, string controller, string areaName ) : base( action, controller, areaName ) {}
/// <summary>
/// Overridden IsValid function
/// </summary>
/// <param name="value"></param>
/// <param name="validationContext"></param>
/// <returns></returns>
protected override ValidationResult IsValid( object value, ValidationContext validationContext )
{
// Find the controller passed in constructor
var controller = GetControllerList().FirstOrDefault( x => x.Name == string.Format( "{0}Controller", this.RouteData["controller"] ) );
if ( controller == null )
{
// Default behavior of IsValid when no controller is found.
return ValidationResult.Success;
}
// Find the Method passed in constructor
var mi = controller.GetMethod( this.RouteData["action"].ToString() );
if ( mi == null )
{
// Default behavior of IsValid when action not found
return ValidationResult.Success;
}
// Create instance of the controller to be able to call non static validation method
var instance = Activator.CreateInstance( controller );
// invoke the method on the controller with value and "AdditionalFields"
JsonResult result;
if ( !string.IsNullOrWhiteSpace( AdditionalFields ) )
{
var additionalField = validationContext.ObjectType.GetProperty( AdditionalFields )
.GetValue( validationContext.ObjectInstance );
result = (JsonResult) mi.Invoke( instance, new [] { value, additionalField } );
}
else
result = (JsonResult)mi.Invoke( instance, new [] { value } );
// Return success or the error message string from CustomRemoteAttribute
string errorMessaqe = result.Data as string;
if (errorMessaqe == null)
{
bool isValid;
try
{
isValid = (bool) result.Data;
}
catch (Exception)
{
isValid = false;
}
return isValid ? ValidationResult.Success : new ValidationResult( base.ErrorMessageString );
}
else
return new ValidationResult( errorMessaqe );
}
}
As has been answered before, this is by design.
I have just stumbled upon a nice article on CodeProject - http://www.codeproject.com/Articles/361113/Extending-the-MVC-RemoteAttribute-to-validate-ser
The problem is that Remove Attribute requires Javascript validation, it does not work out of the box on the server-side... in other words, if you enable javascript validation, it will work and show the error(s), if you disable javascript and go to server validation, it will simply not show any errors on the modelstate, this is not a bug, its a feature hahaha... well, that's the way it was built (on ms)...
https://docs.devexpress.com/AspNet/17294/aspnet-mvc-extensions/data-editors-extensions/common-concepts/validation/remote-validation#requirements
If you need a remote validation attribute that works client and server side, you must create your own class inheriting RemoteAttribute, then you must deploy your own validation, check the following video: https://www.youtube.com/watch?v=qopOqppDwc4&t=110s
The video is almost correct, I did post a comment for controllers that use services via injection like dbcontext, etc... I did it and it works...

ActiveDirectory query performance for not including

I'm curious as to whether the following will negatively impact performance in a significant way...
I have a web form with an input box and grid (could be any form of application really) and allows the user to search Active Directory for users...I don't want user accounts that have the $ as part of there sAMAccountName and so am wondering whether I should have them returned and then filter them out in a loop in the application or whether they should be excluded in the ActiveDirectory filter like the following:
(&(objectCateogry=person)(objectClass=user)(!(sAMAccountName=*$*))(cn=<Insert User Query>))
I guess it's the *$* that i'm concerned will impact performance...any insight would be greatly appreciated!
I would include (!(sAMAccountName=*$*)) in the query for the following reasons:
It is indexed in Active Directory so searches are quick.
In most environments domain controllers aren't hit as hard as web servers and have CPU and RAM to spare.
I'm just guessing but I would think that the extra entries that the domain controllers will have to process and send to the web server would actually make everything take a little longer. You could try it both ways in your environment and measure the difference.
Also, you could take a look at the classes in System.DirectoryServices.Protocols if you're concerned with performance.
The filter about AD as follwing:
class ExpressionTemplates
{
/// <summary>
/// The start with expression. eg: "({0}={1}*)".
/// </summary>
public readonly static string StartWithExpression = "({0}={1}*)";
/// <summary>
/// The end with expression. eg: "({0}=*{1})".
/// </summary>
public readonly static string EndWithExpression = "({0}=*{1})";
/// <summary>
/// The has a value expression. eg: "({0}=*)".
/// </summary>
public readonly static string HasAValueExpression = "({0}=*)";
/// <summary>
/// The has no value expression. eg: "(!{0}=*)".
/// </summary>
public readonly static string HasNoValueExpression = "(!{0}=*)";
/// <summary>
/// The is expression. eg: "({0}={1})".
/// </summary>
public readonly static string IsExpression = "({0}={1})";
/// <summary>
/// The is not expression. eg: "(!{0}={1})".
/// </summary>
public readonly static string IsNotExpression = "(!{0}={1})";
/// <summary>
/// The and expression. eg: "(&{0})".
/// </summary>
public readonly static string And = "(&{0})";
/// <summary>
/// The or expression. eg: "(|{0})".
/// </summary>
public readonly static string Or = "(|{0})";
/// <summary>
/// The parenthesis expression. eg: "({0})".
/// </summary>
public readonly static string Parenthesis = "({0})";
/// <summary>
/// The join expression. eg: "{0}{1}".
/// </summary>
public readonly static string Join = "{0}{1}";
}
You can refer my OSS project which base on ActiveRecord pattern as following(Because it is open source you can find out how to operate the AD with DirectoryEntry, DirectoryEntry is not only support the LDAP protocol but also IIS, WIN and so on, so I develop this lib):
class ComplexFilterUnitTest : BaseUnitTest
{
[TestCase]
public void TestComplexFilter()
{
IFilter filter =
new And(
new IsUser(),
new Is(OrganizationalUnitAttributeNames.OU, "pangxiaoliangOU"),
new Or(
new StartWith(AttributeNames.CN, "pang"),
new And(
new EndWith(AttributeNames.CN, "liu"),
new Is(PersonAttributeNames.Mail, "mv#live.cn")
)
)
);
Assert.AreEqual("(&(objectClass=user)(ou=pangxiaoliangOU)(|(cn=pang*)(&(cn=*liu)(mail=mv#live.cn))))", filter.BuildFilter());
foreach (var userObject in UserObject.FindAll(this.ADOperator, filter))
{
using (userObject)
{
Console.WriteLine(userObject.DisplayName);
}
}
}
}
https://landpyactivedirectory.codeplex.com/documentation
And you will find it easy to operate the AD with it, if you have no interest with it please ignore my answer.
Any question about AD please contact me :)

Resources