Pages

Wednesday, February 12, 2014

Javascript - Work With JSON Datetime

Sometimes when we work with JSON datetimes we get a little stuck, because we want to do all the work client side, using javascript only.

 So, to achieve this, to transform something like this:

"/Date(1392291352347)/"

into this:

"2014-02-13 11:35:52"

we can use a function like this one:

function formatDatetime(jsondate) {

    var match;
    if (jsondate == null || !(match = jsondate.match(/\d+/))) {
        return "";
    }

    var d = new Date();
    d.setTime(match[0] - 0);

    var month = d.getMonth() + 1;
    var day = d.getDate();
    var hour = d.getHours();
    var minute = d.getMinutes();
    var second = d.getSeconds();

    var output = d.getFullYear() + '-' +
    (('' + month).length < 2 ? '0' : '') + month + '-' +
    (('' + day).length < 2 ? '0' : '') + day + ' ' +
    (('' + hour).length < 2 ? '0' : '') + hour + ':' +
    (('' + minute).length < 2 ? '0' : '') + minute + ':' +
    (('' + second).length < 2 ? '0' : '') + second;

    return output;
}

References:
http://stackoverflow.com/questions/9050763/format-date-in-jquery
http://stackoverflow.com/questions/4586424/how-do-i-convert-this-json-datetime

Tuesday, March 12, 2013

Endpoint on ASP.NET page returning JSON from DataTable

I was trying to get an web service, on my aspx page which returned data would be JSON.

The structure of JSON returned usually is something similar to this:

{ "d" :  [ {...}, {...}, {...} ] }

To achieve this, I purpose this approach:


First - Create an WebMethod on your page, at server side, like this:

        [System.Web.Services.WebMethod]
        public static string GetData()
        {
            DataTable dt = GetDataTable();
            
            return BuildJSONFromDT(dt);
        }



Second - Create the method "BuildJSONFromDT"

 

        private static string BuildJSONFromDT(DataTable dt)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();

            List<object> resultMain = new List<object>();

            foreach (DataRow row in dt.Rows)
            {
                Dictionary<string, object> result = new Dictionary<string, object>();
                foreach (DataColumn column in dt.Columns)
                {
                    result.Add(column.ColumnName, "" + row[column.ColumnName]);
                }

                resultMain.Add(result);
            }

            return serializer.Serialize(resultMain);
        }



Third - At client side, do an ajax call with jquery like this:

$.ajax({
        type: "POST",
        async: true,
        contentType: "application/json; charset=utf-8",
        data: "{}",
        url: "page.aspx/GetData",
        dataType: "json",
        success: function (result) {
            var myData = eval(result.d);
            // Work on myData object (JSON)
        },
        error: function (data, textStatus, jqXHR) {
            alert("Error: " + textStatus);
        }
    });



At this point, you should have an valid JSON at client side reflecting your DataTable retrieved on server side.

Hope this helps someone.

Cheers!


Reference:
http://geekswithblogs.net/aghausman/archive/2009/05/16/datatable-to-json.aspx

Monday, August 27, 2012

Request JSON using WCF DS 5.0

So, I was start using WCF OData Services 5.0.1.0 and when I made an ajax call requesting the response in JSON I get the 415 error: "Unsupported media type requested".

Detail: "A supported MIME type could not be found that matches the acceptable MIME types for the request. The supported type(s) 'application/atom+xml;type=feed, application/atom+xml, application/json;odata=verbose' do not match any of the acceptable MIME types 'application/json'".

This happens because the serialization json light format will be part of the OData v3 protocol: "The new serialization format will be part of the OData v3 protocol, and we believe that the much-improved JSON format should be the default response when requesting application/json." (http://blogs.msdn.com/b/astoriateam/archive/2012/04/11/what-happened-to-application-json-in-wcf-ds-5-0.aspx)

In conclusion, you have the next code on your WCF OData Service:
public class api : DataService <DataModel>
{
 public static void InitializeService(DataServiceConfiguration config)
 {
  config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
  config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
 }
}



And to call the service using javascript/jquery you can use the next code for that:
$.ajax({
  type: "GET",
  url: "api.svc/Entity()?$top=10",
  dataType: "json",
  beforeSend: function (xhr) {
    xhr.setRequestHeader("Accept", "application/json;odata=verbose");
  },
  success: function (data) {
    //success func
  },
  error: function (error) {
    //error func
  }
});


References:
http://blogs.msdn.com/b/astoriateam/archive/2012/04/11/what-happened-to-application-json-in-wcf-ds-5-0.aspx
http://blogs.msdn.com/b/astoriateam/archive/2012/04/09/wcf-data-services-5-0-rtm-release.aspx
http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataservices/thread/ae80bb85-ad26-48c4-a399-4d76db5c346b

Wednesday, August 22, 2012

jqGrid - External/Custom Filters (not the filtertoolbar)

So, I had the need to filter an jqgrid data, but without using the in-built filtertoolbar (btw is really good...).

To achieve this objective, we have to make the reload of the grid with the new filters... manually...

Now, to filter we need to add/alter the postdata.filters.rules object of the grid. With the search I made, I came up with this function that, perhaps, can help someone...

function OnChangeGridSelect (fieldName, searchText) {    
    var filterObj = {"field":fieldName,"op":"eq","data":searchText};
    var grid = jQuery("#GridID");
    var postdata = grid.jqGrid('getGridParam', 'postData');

    if(postdata != undefined 
       && postdata.filters != undefined 
       && postdata.filters.rules != undefined) 
    {
        //Remove if current field exists
        postdata.filters.rules = $.grep(postdata.filters.rules, function(value) {
            if(value.field != fieldName)
                return value;
        });

        //Add new filter
        postdata.filters.rules.push(filterObj);
    }
    else 
    {
        $.extend(postdata, {
            filters:  { 
                "groupOp":"AND",
                "rules":[ filterObj ] 
            }
        });
    }

    grid.jqGrid('setGridParam', { search: true, postData: postdata });
    grid.trigger("reloadGrid", [{ page: 1}]);
}

explaining the parameters of the above function:
- fieldName is the internal name of the collumn we want to filter with
- searchText is the text from you want to filter the grid.

In my example, the function is called inside combos's events with the necessary parameters.

Approximate result...

















If you don not know the jqgrid here are a couple of links to get into:
http://trirand.com/blog/jqgrid/jqgrid.html
http://www.trirand.com/jqgridwiki/doku.php

Cheers


References:
http://stackoverflow.com/questions/4492963/jqgrid-client-side-searching
http://stackoverflow.com/questions/5749723/jqgrid-filtering-records
http://www.codeproject.com/Articles/58357/Using-jqGrid-s-search-toolbar-with-multiple-filter#pre4
http://stackoverflow.com/questions/2674471/add-own-search-parameter-in-jqgrid-in-asp-net-mvc#answer-2679599

Thursday, February 09, 2012

Using JQuery To Alter Sharepoint Toolbar Menu Item

So... I was trying to change the text of a menu option on a list toolbar in Sharepoint 2007 like this one...








The Purpose of this was to change the text on the menu without changing the content type name. This is really needed when you extend your sharepoint at the point that to change a content type name is not worthy!

After some search, I found a really simple way to do it! check it above.

//Get tag  and change it's attribute
$("ie\\:menuitem[text='Request']").attr("text", "Order");



References:
http://sharepoint.stackexchange.com/questions/2195/modification-of-layouts-upload-aspx

Friday, January 06, 2012

XSL transformation on XML document Using C#

Here is a pretty simple way for transforming an XML document using XSL through C#.

First you get your XML file, by string or file location using Load method, then using XmlTextWriter and XmlTextReader you apply the XSL and get the result on a StringBuilder... It seems cool right?

Now, what have bring you here... the code...


XmlDocument doc = new XmlDocument();
doc.LoadXml("Xml as a String");

StringBuilder resultString = new StringBuilder();
using (XmlTextWriter xmlWriter = new XmlTextWriter(new StringWriter(resultString)))
{
    using (XmlTextReader xmlReader = new XmlTextReader(new StringReader(doc.OuterXml)))
    {
        string xslUrl = "http://YourHost/xsl/stylesheet.xsl";
        System.Xml.Xsl.XslCompiledTransform xslTransform = new System.Xml.Xsl.XslCompiledTransform();
        xslTransform.Load(xslUrl);
        xslTransform.Transform(xmlReader, xmlWriter);
    }
}
                
XmlDocument doc2 = new XmlDocument();
doc2.LoadXml(resultString.ToString());



Cheers!

References:
http://stackoverflow.com/questions/982600/net-xslt-transformation-is-this-really-streamed
http://msmvps.com/blogs/coad/archive/2004/04/13/4994.aspx
http://www.csharpfriends.com/Articles/getArticle.aspx?articleID=63
http://support.microsoft.com/kb/307322/en-us
http://www.codeproject.com/KB/cs/xsltrafo.aspx

Wednesday, October 26, 2011

Sharepoint Timer Job in One Server Only Chosen By You

Ok, this is one scenario that can occur many times! For instance, you have a farm with 4 servers and you want to deploy one Sharepoint Timer Job with site collection scope but you need it to run in an specific server (whatever reasons you have). If you do not indicate what server to run, the installation will install the job in the server that is the admin one (not pretty sure on this one) or, ultimately you will have the same job replicated in every server.

You can see a very good base example how to build an sharepoint timer job here (Andrew Connell Blog), and I will focus this post on how to chose a server to run, not how to install it.

So, to do this, and taking the Andrew Connell's example, you have to do three things:

  • Add a new constructor at SPJobDefinition
  • Get the server you want (SPServer instance)
  • Use the new constructor that implements a different SPJobLockType regarding the example taken

At this time, you are already thinking, "come on!!! some me some code!!!" here it is...

At class that is inheriting the SPJobDefinition you add this constructor
Than, at FeatureActivated method in the TaskLoggerJobInstaller class (the one that inherits from SPFeatureReceiver) you get the server instance you want the job get up and running and use the new constructor added above
























As you can see, you can get the SPServer only by his name (Const.SERVER is a string with server name). But the key here, is the SPJobLockType because you have three choices to use it and to guarantee that it gets register in specific server you chose Job option as you can see in the new constructor. The next image is very self explanatory.













In conclusion, with three simple steps, we can centralize our timer jobs in one specific server making use of the option Job of SPJobLockType and SPServer together. Some warnings... Do not try coding the SPServer with SPJobLockType ContentDatabase, it will fail because you can not do it. On the Execute method, regarding the example, do not use the SPContentDatabase to get the SPSite, use the SPWebApplication, something like this SPSite site = webApplication.Sites[SiteUrl];

References:
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.spjobdefinition_members.aspx
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.spjoblocktype.aspx
http://www.andrewconnell.com/blog/articles/CreatingCustomSharePointTimerJobs.aspx
http://social.msdn.microsoft.com/Forums/en/sharepointdevelopment/thread/8a9b9054-ce04-4536-a537-1b2a4f34ca72