Tuesday, April 11, 2017

Advanced configuration and implementation in enabling Cross-Origin Requests in ASP.NET Web API 2

After we deploy the Web Api or WCF to cloud or in the public network. It means that we already expose the data to any one who know the url of the Web Api or WCF.

I will skip the introduction to setting up the Cross-Origin Requests in ASP.NET Web API 2 here.

For more information about the CORS for Web Api. you can visit MSDN link

Enabling Cross-Origin Requests in ASP.NET Web API 2


i will only focus on the a little bit advance topic on CORS implementation, since i had spend
extend period of time to complete the implementation.


1. control the CORS with custom setting in web.config file.

the configuration setting will allow us to add more domains without any code change and depolyment, we only need system admin to add more domain in the name attribute that separate by
comma.

<configSections>
    <section name="CORSSettings" type="MyApp.CORSSettings, MyApp" />
  </configSections>


 <CORSSettings>
    <CorsSupport>
      <Domain Name="http://firstdomain,http://seconddomain,http://thirddomain" AllowMethods="*" AllowHeaders="*" AllowCredentials="true">
      </Domain>
    </CorsSupport>
  </CORSSettings>


2. Server Side Implementation  

 In the WebApiConfig class

added the following code to enable the CORS globally

var cORSSettings = ConfigurationManager.GetSection("CORSSettings") as CORSSettings;
            if (cORSSettings == null)
                throw new InvalidOperationException("Missing CORS configuration");
            var domains = cORSSettings.CorsSupport.OfType<CorsDomain>();
            foreach (var domain in domains)
            {
                var cors = new EnableCorsAttribute(domain.Name, domain.AllowHeaders, domain.AllowMethods);
                cors.SupportsCredentials = true;
                config.EnableCors(cors);
            }

please ensure the CORS object with property SupportsCredentials to be True, if your web api is configured with windows authentication and disable anonymous access. otherwise you will always receive XMLHttpRequest Network Error




3. Client Side Implementation

Even though you have enable the cors with SupportCredentials, you still will encouter the PreFlight request OPTIONS Error like
  "Origin http://YourDomain is not allowed by Access-Control-Allow-Origin"

when you use .ajax the jquery wrappper to execute the client call

$.ajax({
    type: 'get',
    url: 'http://www.example.com/api/test',
    xhrFields: {
        withCredentials: true
    }

actually we should use this XMLHttpRequest directly to call the web api to solve the preFlight request OPTIONS Error


                    var xmlHttpRequest = new XMLHttpRequest();
                    xmlHttpRequest.open('GET', sWCFUrl, true);
                    xmlHttpRequest.withCredentials = true;
                    xmlHttpRequest.onreadystatechange = processData;
                    xmlHttpRequest.send();
     

 I hope this post can help solve the headache on CORS implementation especiallly with windows authentication eanble and anonymous access diable.







How to use JSOM to get the list of documents from SharePoint Document Library

there are so many way to perform a task that iterating the list of document inside the docoumnt library. we can do either with CSOM with C# or JSOM with Javascript.

Here i will show a very simple way to execute this task.

<script type="text/javascript">
function getDocuments(title) {
   var context = SP.ClientContext.get_current();
   var web = context.get_web();
   var docLibrary = web.get_lists().getByTitle();
//here we can use SP.CamlQuery to filter the list if we need to
//load the the document by certain criteria.
   var items = docLibrary.getItems(SP.CamlQuery.createAllItemsQuery());
   context.load(items,"Include(File)");
   context.executeQueryAsync(
     function () {
        if (items.get_count() > 0) {
            var e = items.getEnumerator();
            while (e.moveNext()) {
                var item = e.get_current();
                var file = item.get_file();
                var title = file.get_title();
                var name = file.get_name();
                console.log(title + "      " + name );
            }
        }
     },
     function (sender, args) {
        console.log("Error in Loading Documents: " + args.get_message());
     }
     );
}



// We will use the delegate function to allow the ExecuteOrDelayUntilScriptLoaded function
//run a function with paramenters and this fucntion will ensure that sp.js is sucessfully loaded
//before running getDocuments function.

$(document).ready(function () {
   ExecuteOrDelayUntilScriptLoaded(function() {getDocuments("Sales Documents")}, "sp.js");
});
</script>


For more information please visit the following link from MSDN

How to: Retrieve List Items Using JavaScript

Friday, March 31, 2017

How to configure a WCF service running like Rest Service?

I have various posts on the configure of WCF. i will show you another configure if you want your WCF service to call with rest service call like

http://WCFHostServer/myWCF.svc/YourMethod

Note to be taken:

1. must use the webHttpBinding.
2. enable HttpsGet in service behaviors setting
3. add <webHttp> to endpoint behavior setting.

here is WCF configuration in my sample wcf application

  <system.serviceModel>
    <services>
      <service name="MyWCF"
               behaviorConfiguration="MyWCF.Service1Behavior">
        <endpoint address="" binding="webHttpBinding" behaviorConfiguration="EndPointBehavior"
                  contract="MyWCF.IMyWCF"
                    bindingConfiguration="wbBind">
          </endpoint>
          </service>
        </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MyWCF.Service1Behavior">
          <serviceMetadata httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false"/>
          <serviceCredentials>
            <windowsAuthentication allowAnonymousLogons="False" includeWindowsGroups="True"/>
          </serviceCredentials>
          </behavior>
        </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="EndPointBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <webHttpBinding>
        <binding name="wbBind">
          <security mode="Transport">
            <transport clientCredentialType="Windows" proxyCredentialType="Windows"/>
            </security>
            </binding>
          </webHttpBinding>
    </bindings>
  </system.serviceModel>

How to add an event handle to dynamic generated HTML content?

when we have a static web content, we can add an javascript function to the element on Doccument.ready Event.

<table><tr id="myRow"><td></td></tr><table>

in  $(document).ready(function () {
    $("myRow").onClick(function(event){
        var $this = $(this);
        var tbody= $(this).closest('tbody').next('tbody');
        if (tbody.hasClass("collapsed")) {
            var img=$this.find('.expandImg');
            $this.find('.expandImg').attr("src","/_layouts/images/minus.gif");
            tbody.removeClass("collapsed");
        } else {
            tbody.addClass("collapsed");
            $this.find('.expandImg').attr("src","/_layouts/images/plus.gif");
        }
}

However, if the html content is created in the fly. then click event no longer work,
we should use the .live() instead of onClick
$(".myRow").live('click', function(event){
        var $this = $(this);
        var tbody= $(this).closest('tbody').next('tbody');
        if (tbody.hasClass("collapsed")) {
            var img=$this.find('.expandImg');
            $this.find('.expandImg').attr("src","/_layouts/images/minus.gif");
            tbody.removeClass("collapsed");
        } else {
            tbody.addClass("collapsed");
            $this.find('.expandImg').attr("src","/_layouts/images/plus.gif");
        }

Tuesday, March 21, 2017

How to use the css file in the Nintex Form to customize the layout

it is quick convenient if we can have a css file to control the layout of the Nintex form, This approach will allow us to modify the change in the css file to fix all layout isse in the nintex. we did not have to open all the forms one by one and modify the css in the Custom CSS Section in the Form Setting Window




Actually we can use the Custom CSS Includes Section to add a link reference pointing to the path of the css file



we only have to refresh the page to get the change in affect. in my case, i put my css stylesheet under the style library in the same sharepoint site

Site URL/Style%20Library/CSS/AdminAccessControlForm.css










Thursday, February 16, 2017

How to force outlook download all items from exchange server after I clear all the offline emails.

I try to clear the cache to see if i can get all the emails shown in my outlook.

i right click on my inbox folder to get this popup window





then click on the clear offline itmes, then all my emails are gone from my outlook window.

I try to use update Folder button from the SEND/RECEIVE menu




but the Inbox did not load any items from exchange server.

after consult with the network administration, here is the solution

1. go the folder that store the outlook data file

C:\Users\YourUserName\AppData\Local\Microsoft\Outlook

2. rename the Outlook Data File to other name, then close the outlook and skype for business.

3. re-launch the outlook application, boom the outlook will rebuilt the outlook data file and download all the emails items from the exchange server.