‘ILoggerFactory’ does not contain a definition for ‘AddLog4Net’ and no accessible extension method

To fix this issue you need to run the npm command to install the MS Extension.

If you are getting this error:

‘ILoggerFactory’ does not contain a definition for ‘AddLog4Net’ and no accessible extension method ‘AddLog4Net’ accepting a first argument of type ‘ILoggerFactory’ could be found (are you missing a using directive or an assembly reference?)

You will need to add this extension to our project: [ link ]

Run this NUGET Command from the Package Manager Console in Visual Studio.

install-package Microsoft.Extensions.Logging.Log4Net.AspNetCore

 

Select with optgroup via ajax and mvc controller

I had a need to bind a select control to a set of json data delievered via a  $ ajax call…

 

C# method

 public List<SelectListItem> changeHistorySelect { get; private set; }

        [AcceptVerbs(HttpVerbs.Get)]

        public ActionResult GetChangeHistorySelect(Int64 Id)
        {
            var selectListGroup_Info = new SelectListGroup() { Name = "Info"};
            var selectListGroup_Allotments = new SelectListGroup() { Name = "Allotments" };
            var selectListGroup_Financial = new SelectListGroup() { Name = "Financial" };
            var selectListGroup_Daily_Status = new SelectListGroup() { Name = "Daily Status" };
            var selectListGroup_Enrollments = new SelectListGroup() { Name = "Enrollments" };

            #region  Misc Code...

            // Build list
            changeHistorySelect = new List<SelectListItem>
            {
              new  SelectListItem
              {
                  Value = "",
                  Text = "- Select -",
                  Selected = true
                 
              },
                new SelectListItem
                {
                    Value = "student",
                    Text = "Student",
                    Group = selectListGroup_Info
                },
                new SelectListItem
                {
                    Value = "altAddresses",
                    Text = "Alternate Addresses",
                    Group = selectListGroup_Info
                },
                new SelectListItem
                {
                    Value = "enrollment",
                    Text = "Enrollment",
                    Group = selectListGroup_Info
                },
                new SelectListItem
                {
                    Value = "enrollmentType",
                    Text = "Enrollment Type",
                    Group = selectListGroup_Info
                },


                new SelectListItem
                {
                    Value = "allotteeInfo",
                    Text = "Allottee Information",
                    Group = selectListGroup_Allotments
                },

                new SelectListItem
                {
                    Value = "earnings",
                    Text = "Earnings",
                    Group = selectListGroup_Financial
                },
                new SelectListItem
                {
                    Value = "deductions",
                    Text = "Deductions",
                    Group = selectListGroup_Financial
                },
                new SelectListItem
                {
                    Value = "reimbursements",
                    Text = "Reimbursements",
                    Group = selectListGroup_Financial
                },
                new SelectListItem
                {
                    Value = "accruals",
                    Text = "Accruals",
                    Group = selectListGroup_Financial
                },
              
            };

            // Now add enrollments to list

            var enrollments = new StudentChangeHistoryService().GetStudentEnrollment(Id);
            foreach (var er in enrollments)
            {
                if (er.sep_dt.ToString() == "1/1/0001 12:00:00 AM")
                {
                    changeHistorySelect.Add(new SelectListItem
                    {
                        Value = er.enr_dt != null ? er.enr_dt.Value.ToString("MM/dd/yyyy") : String.Empty,
                        Text = "Current Enrollment: " + (er.enr_dt != null ? er.enr_dt.Value.ToString("MM/dd/yyyy") : String.Empty) + " - Current",
                        Group = selectListGroup_Daily_Status
                    });
                }
                else
                {
                    changeHistorySelect.Add(new SelectListItem
                    {
                        Value = er.enr_dt != null ? er.enr_dt.Value.ToString("MM/dd/yyyy") : String.Empty,
                        Text = String.Format("Prior Enrollment: {0} - {1} ", er.enr_dt != null ? er.enr_dt.Value.ToString("MM/dd/yyyy") : String.Empty,(er.sep_dt != null ? er.sep_dt.Value.ToString("MM/dd/yyyy"): String.Empty)), 
                        Group = selectListGroup_Daily_Status
                    });
                }


            }

            var jsonResult = Json(changeHistorySelect);
            #endregion

            return Json(changeHistorySelect,JsonRequestBehavior.AllowGet);
        }

Now I need to have the UI call and build selector in javascript


 function getChangeHistorySelect(studentId) {

            $.getJSON('@Url.Action("GetChangeHistorySelect")', { Id: studentId }).done(function (data) {

                console.log(data);
                var result = data;

                var changeHistorySelect = $('#changeHistorySelect');
                changeHistorySelect.empty();
                var groupName = '';
                var groupPreviousName = '';
                $.each(result,
                    function () {
                        // Need an outloop for the option group
                       // debugger;
                        if (this.Group != null) {
                            // Has the group already been added?
                            var group = this.Group;
                            if (groupName === '') {

                                groupName = group.Name;
                                groupPreviousName = groupName;
                                // First Add...
                                changeHistorySelect.append(
                                    $('<optgroup>',
                                        {
                                            label: groupName,
                                            id: groupName
                                        }));


                            } else {
                                groupName = group.Name;
                                // A group has already been added... does it match?
                                if (groupPreviousName === groupName) {
                                    // They Match skip (added select under this group
                                } else {
                                    // They don' match, add new optGroup and contiue on to add selects under it
                                    groupName = group.Name;
                                    groupPreviousName = groupName;

                                    changeHistorySelect.append(
                                        $('<optgroup>',
                                            {
                                                label: groupName,
                                                id: groupName.replace(/\s/g, "")
                                            }));
                                }
                            }
                            // Add Option Group
                            var custom = $('#' + groupName.replace(/\s/g, ""));
                            var option = $("<option></option>");
                            option.val(this.Value);
                            option.text(this.Text);
                            option.appendTo(custom);


                        } else {
                            changeHistorySelect.append(
                                                           $('<option>',
                                                               {
                                                                   value: this.Value
                                                               }).text(this.Text)
                                                       );
                        }

                    });

            });
        }


.

 

 

 

 

 

 

I promise, just wait will ya while I do…

A traditional synchronous callback structure versus asynchronous promise equivalent

synchronous

try {
  var value = myFunction();
  console.log(value);
} catch(err) {
  console.log(err);
}

asynchronous

myFunction().then(function(value) {
  console.log(value);
}).catch(function(err) {
  console.log(err);
});

 

In the sync example you would have to wait until myfunction completed before any more code could be executed.  I am sure you have seen sites where the browser UI seems locked up or non-responsive… this kind of code can be the culprit.

The second example returns a promise for the value, then the rest of the code can carry on.  Like rendering a GRID that will hold the data the promise is fetching…  etc…

 

 

 

WEB API 2

In the past you had to configure http responses like this:

 throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));

or

 return new HttpResponseMessage(HttpStatusCode.OK);

 

Now you can do the following:

 public IHttpActionResult GetProduct(int id)
 {
 var product = products.FirstOrDefault((p) => p.Id == id);
 if (product == null)
 {
 return NotFound();
 }
 return Ok(product);
 }

Here are a few articles about it and a working example download

Download will work in VS 2015 or 2017 – just make sure you unlock after unzipping and use package manager to restore packages in vs.

ApiController helper methods like OK)_, NotFound() and more…

Name Description
System_CAPS_protmethod BadRequest()

Creates a BadRequestResult.

System_CAPS_protmethod BadRequest(ModelStateDictionary)

Creates an InvalidModelStateResult with the specified model state.

System_CAPS_protmethod BadRequest(String)

Creates an T:System.Web.Http.Results.ErrorMessageResult (400 Bad Request) with the specified error message.

System_CAPS_protmethod Conflict()

Creates a ConflictResult (409 Conflict).

System_CAPS_protmethod Content<T>(HttpStatusCode, T)

Creates a <see cref=”T:System.Web.Http.NegotiatedContentResult`1″ /> with the specified values.

System_CAPS_protmethod Content<T>(HttpStatusCode, T, MediaTypeFormatter)

Creates a <see cref=”T:System.Web.Http.FormattedContentResult`1″ /> with the specified values.

System_CAPS_protmethod Content<T>(HttpStatusCode, T, MediaTypeFormatter, MediaTypeHeaderValue)

Creates a <see cref=”T:System.Web.Http.FormattedContentResult`1″ /> with the specified values.

System_CAPS_protmethod Content<T>(HttpStatusCode, T, MediaTypeFormatter, String)

Creates a <see cref=”T:System.Web.Http.FormattedContentResult`1″ /> with the specified values.

System_CAPS_protmethod Created<T>(String, T)

Creates a CreatedNegotiatedContentResult<T> (201 Created) with the specified values.

System_CAPS_protmethod Created<T>(Uri, T)

Creates a CreatedNegotiatedContentResult<T> (201 Created) with the specified values.

System_CAPS_protmethod CreatedAtRoute<T>(String, IDictionary<String, Object>, T)

Creates a CreatedAtRouteNegotiatedContentResult<T> (201 Created) with the specified values.

System_CAPS_protmethod CreatedAtRoute<T>(String, Object, T)

Creates a CreatedAtRouteNegotiatedContentResult<T> (201 Created) with the specified values.

System_CAPS_pubmethod Dispose()

Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

System_CAPS_protmethod Dispose(Boolean)

Releases the unmanaged resources that are used by the object and, optionally, releases the managed resources.

System_CAPS_pubmethod Equals(Object)

(Inherited from Object.)

System_CAPS_pubmethod ExecuteAsync(HttpControllerContext, CancellationToken)

Executes asynchronously a single HTTP operation.

System_CAPS_protmethod Finalize()

(Inherited from Object.)

System_CAPS_pubmethod GetHashCode()

(Inherited from Object.)

System_CAPS_pubmethod GetType()

(Inherited from Object.)

System_CAPS_protmethod Initialize(HttpControllerContext)

Initializes the ApiController instance with the specified controllerContext.

System_CAPS_protmethod InternalServerError()

Creates an InternalServerErrorResult (500 Internal Server Error).

System_CAPS_protmethod InternalServerError(Exception)

Creates an ExceptionResult (500 Internal Server Error) with the specified exception.

System_CAPS_protmethod Json<T>(T)

Creates a JsonResult<T> (200 OK) with the specified value.

System_CAPS_protmethod Json<T>(T, JsonSerializerSettings)

Creates a JsonResult<T> (200 OK) with the specified values.

System_CAPS_protmethod Json<T>(T, JsonSerializerSettings, Encoding)

Creates a JsonResult<T> (200 OK) with the specified values.

System_CAPS_protmethod MemberwiseClone()

(Inherited from Object.)

System_CAPS_protmethod NotFound()

Creates a NotFoundResult.

System_CAPS_protmethod Ok()

Creates an OkResult (200 OK).

System_CAPS_protmethod Ok<T>(T)

Creates an OkNegotiatedContentResult<T> with the specified values.

System_CAPS_protmethod Redirect(String)

Creates a redirect result (302 Found) with the specified value.

System_CAPS_protmethod Redirect(Uri)

Creates a redirect result (302 Found) with the specified value.

System_CAPS_protmethod RedirectToRoute(String, IDictionary<String, Object>)

Creates a redirect to route result (302 Found) with the specified values.

System_CAPS_protmethod RedirectToRoute(String, Object)

Creates a redirect to route result (302 Found) with the specified values.

System_CAPS_protmethod ResponseMessage(HttpResponseMessage)

Creates a ResponseMessageResult with the specified response.

System_CAPS_protmethod StatusCode(HttpStatusCode)

Creates a T:System.Web.Http.StatusCodeResult with the specified status code.

System_CAPS_pubmethod ToString()

(Inherited from Object.)

System_CAPS_protmethod Unauthorized(AuthenticationHeaderValue[])

Creates an UnauthorizedResult (401 Unauthorized) with the specified values.

System_CAPS_protmethod Unauthorized(IEnumerable<AuthenticationHeaderValue>)

Creates an UnauthorizedResult (401 Unauthorized) with the specified values.

System_CAPS_pubmethod Validate<TEntity>(TEntity)

Validates the given entity and adds the validation errors to the model state under the empty prefix, if any.

System_CAPS_pubmethod Validate<TEntity>(TEntity, String)

Validates the given entity and adds the validation errors to the model state, if any.