Monday, 23 December 2013

This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. - MVC


MVC by default does not allow the methods to be fetched directly which does return a JSON result due to security reasons. Request behavior shall be marked explicitly to allow to do a get operation.

return Json(data, JsonRequestBehavior.AllowGet)

Once you add this "JsonRequestBehavior.AllowGetOn" it allows to do a get operation to return the JSON result to browser.
 

Unable to load the specified metadata resource entity framework - Entity Framework


Few days before I have encountered the error "Unable to load the specified metadata resource entity framework" while loading the application. After changing the connecting string from as defined below my problem got sorted out.

From

connectionString="metadata=res://*/Data.System.csdl|res://*/Data.System.ssdl|res://*/Data.System.msl";

To

connectionString="metadata=res://*/;<remainingpart>

Thursday, 19 December 2013

The ViewData item that has the key '' is of type 'System.Int32' but must be of type 'IEnumerable'. - MVC



Some times you end up with this error in MVC saying "
The ViewData item that has the key ''is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'."
 
There are 2 possible reasons that this could happen.
 
One is that if you have a view where you are displaying a dropdownlist but you are not returning a list to it and it tries to read the Id value from your entity and it says that it is expecting a list and what you returning is not a list.
 
So probably you resend the data by converting to .ToList()
 
Second scenario would be you have do a create operation and forget it to redirect to index page and being in the same page again and if you don't fill your view bag again with that dropdownlist value that you populating then it would throw that error back.

Wednesday, 18 December 2013

"The model item passed into the dictionary is of type 'System.Data.Entity.Infrastructure.DbQuery`1[System.Boolean]', but this dictionary requires a model item of type -" ASP.Net MVC


The model item passed into the dictionary is of type 'System.Data.Entity.Infrastructure.DbQuery`1[System.Boolean]', but this dictionary requires a model item of type

 

This error would appear when the Controller return the result which is not of type that View is expecting if your view is tightly bound with the model.

Also note that whether you returning a single item of object or returning a collection, even though you return the same object if it is a collection then it would throw back this error.

 

"Cannot open serverrequested by the login. Client with IP address is not allowed to access the server" while accessing SQL Azure



When you are using SQL Azure Database you may end up with this error ""Cannot open server requested by the login. Client with IP address is not allowed to access the server" at time development. This is due to because you Azure firewall settings does not allow you system to access the sql server as it is not been listed as permitted IPs . To do the following you can login to windows azure and select your database and choose the menu option dashboard as show below.


You can click on manage and it does automatically reads your IP and prompts to add that in the permitted IP list as shown below.

Once you say OK now you are good to go and access your database from your development environment.

Context has changed since the database was created. Consider using Code First Migrations to update the database - Entity Framework - ASP.Net



This error occurs when the database is not in sync with your data model. If you enable Code First migrations then it updates the database back based on your data model. You can do this through Package Manager. In Visual Studio select Tools -> Library Package Manager -> Package Manager Console and run the following commands to enable Code First Migrations.





PM> Enable-Migrations –EnableAutomaticMigrations

PM>  Update-Database –Verbose

It does show the update logs as well to see the migration happening.
 

Tuesday, 10 December 2013

Bundling and Minification in ASP.Net 4.5


 
Bundling and Minification
 
There is a lot of buzz now a days around this and definitely it is worth to know about this fabulous concept introduced by Microsoft which drastically improves the performance of the page. Even though it is bit late to come up with this but still it is good that Microsoft has come up with this concept.
 
As a developer we always see or have many number of Javascript and Style sheet files that we use in our pages and we always have these in multiple files which is recommended to have better maintainability.
But this also adds up to performance issue because of no round trips that needs to be made to server in order to fetch the data from server.
Now a days all the browsers are restricting their browsers to serve only 6 requests at a time per host. If you observe the below figure you can observe that first 6 resources are been requested and others are under waiting to get their turn to perform the request.



Red Bars indicate that the request is queue by browser waiting for the six connections to be completed.
 
Bundling
Bundling is a new concept that’s has come up now which drastically reduces the no of hits made to server and proportionately the time taken to perform the request. It converts the chunk of files to one file and you see that it makes a single request to acquire entire folder data. The following sample is based on MVC application but the same can be achieved in normal ASP.Net web application.
public class BundleConfig
    {
        // For more information on Bundling, visit http://go.microsoft.com/fwlink/?LinkId=254725
        public static void RegisterBundles(BundleCollection bundles)
        {
            bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                        "~/Scripts/jquery-{version}.js"));
 
            bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
                        "~/Scripts/jquery-ui-{version}.js"));
 
            bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                        "~/Scripts/jquery.unobtrusive*",
                        "~/Scripts/jquery.validate*"));
 
            // Use the development version of Modernizr to develop with and learn from. Then, when you're
            // ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
            bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
                        "~/Scripts/modernizr-*"));
 
            bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css"));
 
            bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(
                        "~/Content/themes/base/jquery.ui.core.css",
                        "~/Content/themes/base/jquery.ui.resizable.css",
                        "~/Content/themes/base/jquery.ui.selectable.css",
                        "~/Content/themes/base/jquery.ui.accordion.css",
                        "~/Content/themes/base/jquery.ui.autocomplete.css",
                        "~/Content/themes/base/jquery.ui.button.css",
                        "~/Content/themes/base/jquery.ui.dialog.css",
                        "~/Content/themes/base/jquery.ui.slider.css",
                        "~/Content/themes/base/jquery.ui.tabs.css",
                        "~/Content/themes/base/jquery.ui.datepicker.css",
                        "~/Content/themes/base/jquery.ui.progressbar.css",
                        "~/Content/themes/base/jquery.ui.theme.css"));
        }
    }
 
So if you observe the above code we have a class by name BundleConfig(Could be named anything) and we have a static method saying RegisterBundles which takes existing bundle collection as input and updated the new bundles.
If you observe the following code line
bundles.Add(new ScriptBundle("~/bundles/jquery").Include("~/Scripts/jquery-{version}.js"));
 
You can notice that we have class called ScriptBundle and in which we are passing ("~/Scripts/jquery-{version}.js”) this notates that we are create a bundle by name "~/bundles/jquery" and we are including all the files in scripts folder which matches the pattern “jquery-{version}.js”
 
Similar logic with all other bundles. Once we are done creating bundles we need to include them to application to access them where ever we want. In Global.asax we need to register this bundles as shown below.
 
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
 
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();
        }
    }
 
 
And once it is done we can use them where we want to call them. As shown below this can be used in cshtml
 
        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
Also note that you need make compilation debug attribute set to false if bundling to be active.
 
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
Look at the screen shot below which gives clear picture about how it reduced drastically the no of hits made to server.

 
 
 
 
Minification
 
I create a sample function as shown below
function TestFunction(BigVariable, VeryBigVariable) {
    return BigVariable + VeryBigVariable;
}
 
And when you execute the page and look at developer tools search for TestFunction you can see that it minifies the variable names to smaller ones like as shown in the screen shot is has converted BigVariable to “n” and VeryBigVariable to “t” and also reduces the extra spaces as shown below.

This way it really redcues the size of file and also makes it very lighter weight to download.
 Hope this helps.
 
 
 

 
 
 

Saturday, 7 December 2013

SQL Server Performance Tuning - 1


This is one of the topics that interests me throughout my career. Thought to put down few cents of my experience in this world.

1. Always have a primary key on every table that you create.

2. Identify those columns which acts as key columns on the table for search. Keep those keys as Non-Clustered indexes.

3. Specify SET NOCOUNT ON on each stored procedure that you create, saves time from counting on.

4.  Very old and familiar tip, return only those columns that you require it.

5. Reduce the no of round trips you make to the database probably returning multiple datasets.

6. Well-designed indexes can reduce disk I/O operations system resources will be consumed less and also improves performance.  A best example of a non-clustered index is imagine a book with clustered index as the index at the start of the book and Non-Clustered index as the index at the end of the book which is sorted by name. Imagine if you don't have index sorted by name at end of book and you want to read about a topic say Polymorphism, you need to completely scan the book to find the topic. This is how exactly the use of non-clustered index in a database which helps to do a optimum search based on a field you generally look for.

7.  One of the query tips is to reduce the use of Cursor, one way to achieve is use a  CASE statement if it fulfills the requirement.

8. Try to use LEFT JOIN instead of NOT IN for the better performance. But it is not always true that left outer join gives the better results. Always use profile to understand the performance and choose the better option for better results.

9. Reduce Joins as much as possible, every join that table has to make, it has to literally map each and every row in other table which is definitely a huge performance impact.

10. Avoid using IN and NOT IN, instead better use EXISTS and NOT EXISTS

11. Try to reduce sub queries as much as possible.

12. Reduce the usage of triggers instead use CONSTRAINTs or Stored Procedures to perform the job better.

13. Use a table variable instead of temp table if no of rows are less, but if no of rows are more then better use temp table. But the other side temporary table has the ability to have clustered indexes which would definitely boost up the performance , so better test it and use the appropriate one.

Will continue few more in my later posts.





 

Friday, 6 December 2013

Sampe WCF Rest Service , Along with accessing CROSS Domain Service, also access JSON request by Javascript and also in Dynamics CRM



Most of us would have faced the problem of "Access Denied" or "Transport Error" while accessing cross domain calls from CRM.

I have a small example here with a sample WCF service along with JSONP Query below to fetch the data from Cross Domain Service


Create a Sample WCF Application by selecting the "WCF Service Application" template from Projects as shown below.




We are just creating a sample method which takes bookid as parameter and returns the same. Use the following code to create an interface and class method.


///Interface which has the method GetBookByID

namespace WcfRestSample
{
    [ServiceContract]
    [System.Web.Script.Services.ScriptService]
    public interface IBookService
    {
        [OperationContract]
        [WebInvoke(Method="GET",ResponseFormat=WebMessageFormat.Json,BodyStyle=WebMessageBodyStyle.Wrapped,UriTemplate  = "Book/{id}")]

        Book GetBookById(string id);
    }
}


If you observe the attributes "WebMessageFormat.Json" specifies that the response format from the service shall be JSON and we also provided the rest format like "Book/{id}"  to call the service.


We have a class implementing the service which provides the implementation of the method




 Please make the following changes in the config file to make it Rest based JSON Service

 If you observe keenly there are two major things you need to consider , one to enable the service as RestBased Service you need to set Binding as "webHttpBinding" and the other crossDomainScriptAccessEnabled="true" , this makes the service accessible for cross domain request as well.


Now your service is ready. Let us see how client calls the same using $.getJSON and the other way by using original javascript to read a JSON request. No difference if called in Dynamics CRM or through a normal ASP.Net page


There are two ways to consume the service from Javascript using JSONP

Method 1: $.getJSON to read a JSONP request



 If you observe above code it just uses the URL as it is and at the end of the URL you have "callback=parseRequest" which will call back the method by that name and returns the result.

Method 2 original JavaScript to read a JSONP request

Refer to the following link in MSDN for more details

 

Thursday, 5 December 2013

"Script 1004 expected ;" error while calling WCF JSON Rest based service in Dynamics CRM 2011



I faced the following error while calling a WCF Rest based JSON service from Dynamics CRM 2011

This is used to due to the following setting has not done on the config file


<bindings>

<webHttpBinding>

<binding crossDomainScriptAccessEnabled="true"></binding>

</webHttpBinding>

</bindings>


This enables to set the WCF service to enable for cross domain


 

Wednesday, 4 December 2013

Query options $expand, $filter, $orderby, $inlinecount, $skip and $top cannot be applied to the requested resource Dynamics CRM 2011

This error "Query options $expand, $filter, $orderby, $inlinecount, $skip and $top cannot be applied to the requested resource Dynamics CRM" 

 will be thrown while accessing OData query in the following format


  "/XRMServices/2011/OrganizationData.svc/" + odataSetName  + "$select=fieldi1,field2&$filter=entityid eq guid'" + selectedID + "'";


As the expected result is one record but the OData expected a result set and tries to extract data from it. The above one works fine if the result set expected is more than 1

If the expected result is one record better to use in the following way

 "/XRMServices/2011/OrganizationData.svc/" + odataSetName  +  "(guid'" + id +"')",


Hope this helps if you stuck in that error
 

Tuesday, 3 December 2013

Performing Insert Update Delete Operation on Entity Using OData in Dynamics CRM 2011


This post describes the way to update the entity for all different type of fields in the entity

As shown in the sample below it creates a new account with different set of types

 var account = {};
account.Name = "Test Account Name";
account.Description = "This account was created by the JQueryRESTDataOperations sample.";
if (primaryContact != null) {

  //Set a lookup value
  account.PrimaryContactId = { Id: primaryContact.ContactId, LogicalName: "contact", Name: primaryContact.FullName };

}

 //Set a picklist value
  account.PreferredContactMethodCode = { Value: 2 }; //E-mail

//Set a money value
  account.Revenue = { Value: "2000000.00" }; //Set Annual Revenue

//Set a Boolean value
  account.DoNotPhone = true; //Do Not Allow

 var jsonEntity = window.JSON.stringify(account);

    var serverUrl = Xrm.Page.context.getServerUrl();
    var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc/AccountSet";
    var ODataPath = serverUrl + ODATA_ENDPOINT;
    $.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        datatype: "json",
        url: ODataPath + "(guid'" + accountId + "')",
        data: jsonEntity,
        beforeSend: function (XMLHttpRequest) {
            XMLHttpRequest.setRequestHeader("Accept", "application/json");
            XMLHttpRequest.setRequestHeader("X-HTTP-Method", "MERGE");
        },
        error: function (xmlHttpRequest, textStatus, errorThrown) {
            alert("Status: " + textStatus + "; ErrorThrown: " + errorThrown);
        }
    });


If you observe the about code the following statement defines whether the ODATA call is for update or insert

For Update
            XMLHttpRequest.setRequestHeader("X-HTTP-Method", "MERGE");

For Delete
            XMLHttpRequest.setRequestHeader("X-HTTP-Method", "DELETE");
          
For Insert
           XMLHttpRequest.setRequestHeader("Accept", "application/json");



 

No Transport error while updating record using JSON in Dynamics CRM 2011


"No Transport" error while updating record using JSON in Dynamics CRM 2011


"No Transport" error while doing CRUD operations through ODATA is due to Server URL that is been picked up by xrm.page.context.getserverurl().


For example if you are browsing CRM website using a localhost and using xrm.page.context.getserverurl() it always picks up your serverurl based on what is been stored in database infact what is been used while creating organization for example say instead of accessing as http://localhost/CRMOrgname it may give http://myhost/CRMOrgName


Which is treated by javascript as cross domain and does not allow and says No Transport Error.

Instead og using

var orgURL = xrm.page.context.getserverurl()

USE THIS

var orgURL= "http://" + window.location.host + "/" + Xrm.Page.context.getOrgUniqueName();

which always based on what is the current URL that is been used to browse the CRM org now.


Hope this helps