Home > Software design >  Write our API end point in a standard way to cover all the business scenarios, in our ASP.NET MVC 5
Write our API end point in a standard way to cover all the business scenarios, in our ASP.NET MVC 5

Time:10-24

I have this Action method in ASP.NET MVC 5:

namespace LDAPMVCProject.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult UsersInfo(string username, string password)
        {
            DomainContext result = new DomainContext();

            try
            {
                // create LDAP connection object  
                DirectoryEntry myLdapConnection = createDirectoryEntry();
                string ADServerName = System.Web.Configuration.WebConfigurationManager.AppSettings["ADServerName"];
                string ADusername = System.Web.Configuration.WebConfigurationManager.AppSettings["ADUserName"];
                string ADpassword = System.Web.Configuration.WebConfigurationManager.AppSettings["ADPassword"];

                using (var context = new DirectoryEntry("LDAP://mydomain.com:389/DC=mydomain,DC=com", ADusername, ADpassword))
                using (var search = new DirectorySearcher(context))
                {
                    // validate username & password
                    using (var context2 = new PrincipalContext(ContextType.Domain, "mydomain.com", ADusername, ADpassword))
                    {
                        bool isvalid = context2.ValidateCredentials(username, password);
                        
                        if !(isvalid)
                            return **** // authentication error
                    }

                    // create search object which operates on LDAP connection object  
                    // and set search object to only find the user specified  

                    //    DirectorySearcher search = new DirectorySearcher(myLdapConnection);
                    //  search.PropertiesToLoad.Add("telephoneNumber");
                    search.Filter = "(&(objectClass=user)(sAMAccountName=test.test))";

                    // create results objects from search object  

                    // user exists, cycle through LDAP fields (cn, telephonenumber etc.)  
                    SearchResult r = search.FindOne();

                    ResultPropertyCollection fields = r.Properties;

                    foreach (String ldapField in fields.PropertyNames)
                    {
                        if (ldapField.ToLower() == "telephonenumber")
                        {
                            foreach (Object myCollection in fields[ldapField])
                            {
                                result.Telephone = myCollection.ToString();
                            }
                        }
                        else if (ldapField.ToLower() == "department")
                        {
                            foreach (Object myCollection in fields[ldapField])
                            {
                                result.Department = myCollection.ToString();
                            }
                        }
                       // }
                    }
                    
                    if (result.Telephone == null)
                        return ***** //Telephone is empty

                    if (result.Department)
                        return **** // department is empty

                    string output = JsonConvert.SerializeObject(result);

                    return Content(output, "application/json");//success
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception caught:\n\n"   e.ToString());
            }

            return View(result);
        }
    }
}

The action method acts as an API endpoint for our web application, where the API accepts username & password, and does the following:

  1. Validate the username/password against Active Directory

  2. If valid; check if the telephone number is empty >> if so return an error

  3. If valid; check if department is empty >> if so return an error

  4. If valid and info found; return the department & telephone for the user

Now I am a bit confused on how I need to return the JSON for the first 3 points? Should I always return http 200 with a status message (Status : "success" OR Status: "failed")? or if the username/password validation failed then i should return http 401 without having to return any JSON content?

Can anyone help me with this?

I need to write the action method in a standard way that can be consumed by 3rd party application.

Second question: what do I need to return in case the code raised an exception?

Thanks

CodePudding user response:

There are a lot of ways to go about this and ultimately you want to have your endpoint behave in a way that whoever is consuming your endpoint expects.

I stumbled across this as an interesting way to handle nuanced errors in a request to your endpoint. Even though this is used for Graph API, you could use the concept for your needs. https://developers.facebook.com/docs/graph-api/guides/error-handling. The TL;DR is to have a standardized json response like:

{
  "error": {
    "message": "Message describing the error", 
    "type": "OAuthException", 
    "code": 190,
    "error_subcode": 460,
    "error_user_title": "A title",
    "error_user_msg": "A message",
    "fbtrace_id": "EJplcsCHuLu"
  }
}

CodePudding user response:

The HTTP statuse codes are very flexable and can be confused to tell when to use what. My advice:

  1. Identify the Http status family (X00)
  • 100s: Informational codes: the server acknowledges the request initiated by the browser and that it is being processed (100–199).
  • 200s: Success codes: request received, understood, processed and expected info relayed to browser (200–299).
  • 300s: Redirection codes: a different destination has been substituted for the requested resource; further action by the browser may be required (300–399).
  • 400s: Client error codes: website or page not reached; page unavailable or there was a technical problem with the request (400–499).
  • 500s: Server error codes
  1. Search for the specific Http status code for your response (2XX) here some exemples for the 200 family:
  • 201: Created. Request fulfilled; new resource created. Typical response after POST requests.
  • 202: Accepted. Browser request accepted, still in process. May or may not succeed.

For your example I would return:

  • 403: Forbidden - if the user credentials are wrong.
  • 200: Ok - if everythig works well (all the info returned).

The other option is a little tricky, when the user is authenticate but have no valid data. you can return:

  • 204: No content - because the user is auth but has no data
  • 500: internal server error - because the server cant return the requested object
  • 404: Not found - (not my personal chois but it is an option)

It also depends on your client and you preferences.

Happy coddind :)

  • Related