Friday, July 15, 2016

Chrome Postman interceptor Send XHR requests from postman.

Postman Interceptor

No need of fiddler anymore. It is handy and easy to intercept any web api or api call, xhr request . This is useful tool when you want to intercept any request that is fired from any website.

Installed this powerful extension in chrome. Also ensure you have postman client installed aswell.

Now switch on the interceptor and you can even filter the incoming request to the website.

And you can check the history tab of postman to see the request with output and all request body with details such as form post, post and get requests. 

Sometime the request payload is so high it is usually difficult to copy and it hangs. Chrome is memory hungry.Now after you intercept all request you can even save it as collection and can refer for future reference.


  • Filter your requests
  • See the results just beneath it
  • Or you can view results in postman client and save it as collection.




Finally all you need these?






Tuesday, July 12, 2016

Asp.net MVC : The length of the string exceeds the value set on the maxJsonLength property ?

Introduction:

When you happen to see this exception, i m sure you'll get n number of solutions in stackoverflow and trust me you've to understand your problem very well. There are scenarios based on which each of this solution works and differs.

Problem Statement: 
Json Request body max length issue if in my case was sending large file in encoding format.
we used html 5 filereader api. There could be better solution to handle this we would have used HttpPostedFileBase So on.
But we had some custom implementation and some
design challenges. And the story is i ended up with below exception.
Days of research helped me come up with different
solution.

Exception:

  • System.ArgumentException: Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property.
  • Parameter name: input
  • at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit)
  • at System.Web.Mvc.JsonValueProviderFactory.GetDeserializedObject(ControllerContext controllerContext)
  • at System.Web.Mvc.JsonValueProviderFactory.GetValueProvider(ControllerContext controllerContext)
  • at Castle.Proxies.Invocations.ValueProviderFactory_GetValueProvider.InvokeMethodOnTarget()
  • at Castle.DynamicProxy.AbstractInvocation.Proceed()
  • at Glimpse.Core.Extensions.AlternateMethodContextExtensions.TryProceedWithTimer(IAlternateMethodContext context, TimerResult& timerResult)
  • at Glimpse.Core.Extensibility.AlternateMethod.NewImplementation(IAlternateMethodContext context)
  • at Castle.DynamicProxy.AbstractInvocation.Proceed()
  • at Castle.Proxies.ValueProviderFactoryProxy.GetValueProvider(ControllerContext controllerContext)
  • at System.Web.Mvc.ValueProviderFactoryCollection.GetValueProvider(ControllerContext controllerContext)
  • at System.Web.Mvc.ControllerBase.get_ValueProvider()
  • at System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor)
  • at System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
  • at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)


Solution that didn't work for me:

No web.config settings helped to resolve my issue.
Don't know why


Solution That helped.


Approach - Solution 1:


Created Custom Value provider
as per below stackoverflow answers.


http://stackoverflow.com/questions/9943727/jsonmaxlength-exception-on-deserializing-large-json-objects

The only problem is this woul applied to all controller and all action. Which is kind of security threat as per microsoft they explicetly apply maxJsonlength restriction. So again I want a solution which is very specific to Action of the controller.

Approach - Solution 2: 

Create custom Model binder or Action Filter specific to controller. Due to architecture of our solution this was causing some problem.

In ASP.NET MVC, deserialize JSON prior to or in controller's action method

http://stackoverflow.com/questions/1474896/in-asp-net-mvc-deserialize-json-prior-to-or-in-controllers-action-method


The above solution was not compatible with solution architecture. It is also a compromise of custom validation that we had on model.


Approach 3 : Solution [Cooked Up- Worked For me]


Phill Haack blog caught my eye. It enlightened me to  some sort of brute force solution which in a way suits the overall design setup. This is win win situation.


Sending JSON to an ASP.NET MVC Action Method Argument

http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx/

This liner was breakthrough- Valueprovider vs ModelBinder 
Jonathan had the unique insight to write a custom value provider which received JSON data and serialized it to a dictionary rather than the target object. The beauty of his approach is that this dictionary data is then passed to the default model binder which binds it to the final object with validation!


What worked?


I added custom deserialize json object with Maxvalue in override initialize method of MVC Controller.


protected override void Initialize(RequestContext requestContext)
        {
            if ("Some specific Action")
            {
                requestContext.HttpContext.Request.InputStream.Position = 0;
                StreamReader reader = new StreamReader(requestContext.HttpContext.Request.InputStream);
                string bodyText = reader.ReadToEnd();
                if (String.IsNullOrEmpty(bodyText))
                {
                    // no JSON data               
                }
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                serializer.MaxJsonLength = 2147483647;
                object model = serializer.DeserializeObject(bodyText);
                Dictionary < string, object > backingStore = new  Dictionary < string, object >(StringComparer.OrdinalIgnoreCase);
                AddToBackingStore(backingStore, String.Empty, model);
                ValueProvider = new DictionaryValueProvider<object>(backingStore, CultureInfo.CurrentCulture);             
            }
            else
            {
                base.Initialize(requestContext);
            }
        }

I took AddToBackingStore method implementation from below post.

http://stackoverflow.com/questions/9943727/jsonmaxlength-exception-on-deserializing-large-json-objects


After few struggle my api was working fine but with few roadblock and hiccup ahead.



I realized after fetching data from client side to my action controller i was hitting other api to post this data again. There is long design story , please don't ask me why.. The request was timing out.



I have to add this.. mind it..this is just specific to this action and calling api stuff only not impacting other module. This is stop gap arrangement.


I added this..to overcome httpclient timeout,

 Client.HttpClient.Timeout = new TimeSpan(1, 1, 1);

       // Serialize Request
            string _requestContent = null;
            _requestContent = SafeJsonConvert.SerializeObject(request, this.Client.SerializationSettings);
            _httpRequest.Content = new StringContent(_requestContent, Encoding.UTF8);
            _httpRequest.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json; charset=utf-8");
            // Send Request
            if (_shouldTrace)
            {
                ServiceClientTracing.SendRequest(_invocationId, _httpRequest);
            }
            cancellationToken.ThrowIfCancellationRequested();
            Client.HttpClient.Timeout = new TimeSpan(1, 1, 1);
            _httpResponse = await this.Client.HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false);


Some Configuration: Revisited.

IIS Web server setting


system.webServer
  security
    requestFiltering
      requestLimits maxAllowedContentLength="6291456" /
    /requestFiltering
  /security
/system.webServer

Asp.net System web

httpRuntime maxRequestLength="51200" executionTimeout="3600" enableKernelOutputCache="false" relaxedUrlToFileSystemMapping="true" enableVersionHeader="false" 

Server Script timeout

http://stackoverflow.com/questions/579523/how-do-i-set-the-request-timeout-for-one-controller-action-in-an-asp-net-mvc-app

HttpContext.Server.ScriptTimeout = 300; Or location path="ControllerName/ActionName" httpRuntime executionTimeout="1000"/ /system.web /location


jsonSerialization maxJsonLength

http://stackoverflow.com/questions/5692836/maxjsonlength-exception-in-asp-net-mvc-during-javascriptserializer
This is more applicable when the JsonResult is huge


system.web.extensions
  scripting
    webServices>
      jsonSerialization maxJsonLength="2147483644"/
    /webServices
  
/system.web.extensions
This is more applicable when the Json Request is huge . This didn't work most of the cases. So not fruitful solution whereas this globally applies to all controller action. Security threat.


appSettings
  add key="aspnet:MaxJsonDeserializerMembers" value="150000" /

/appSettings


Few more story to hear. If you have patience to go through.Its worth reading.

http://odetocode.com/blogs/scott/archive/2009/04/27/6-tips-for-asp-net-mvc-model-binding.aspx


Search History:

Why MaxJson was not set to heavenly large value? DOS Attack

https://support.microsoft.com/en-in/kb/2661403

https://support.microsoft.com/en-us/kb/981884

https://social.msdn.microsoft.com/Forums/en-US/c017433c-0872-4689-a558-f0c2f301da10/javascriptserializer-deserialize-large-dictionary?forum=netfxnetcom


What Stackoverflow to offer?

Model Binder - To Deserialize the Json Object

http://stackoverflow.com/questions/13746472/using-modelbinder-attribute-vs-modelbinders-add

Custom Model binder derived from DefaulModelBinder

http://stackoverflow.com/questions/25577747/modelbinder-deserialize-arbitrary-json

In ASP.NET MVC, deserialize JSON prior to or in controller's action method

http://stackoverflow.com/questions/1474896/in-asp-net-mvc-deserialize-json-prior-to-or-in-controllers-action-method

Custom Value Provider 
http://stackoverflow.com/questions/9943727/jsonmaxlength-exception-on-deserializing-large-json-objects



 

Saturday, July 9, 2016

Avoid querystring in Sitecore MVC using Route Redirect Approach

Use Case : Keep Url clean without any querystring parameter. No additional encoding of url string or tampering by user.




Note: This is not something related to Post Redirect Get Pattern in MVC
http://www.asp.net/mvc/overview/security/preventing-open-redirection-attacks
https://en.wikipedia.org/wiki/Post/Redirect/Get


The sitecore web page contains a list of product and click on product item redirect to product detail page without querystring identifier.


Solution:


Idea is to set session at the interim between href event called and destination item page.


In sitecore there will be controller rendering which is loaded as per sitecore item path url. In this controller we can have navigate method without view actionresult instead we return redirect as url. This navigate action is not control by sitecore item in fact is independent controller action which can be called outside sitecore controller rendering.





public partial class ProductController : RenderingBaseController
{

  public virtual ActionResult Navigate(int id)
        {
            _session.Set("Product", id);
             return Redirect("/product/Detail");
        }
}

Route Registration in sitecore solution

public partial class ProductController : RenderingBaseController
{

  public class MyAreaRegistration : AreaRegistration 
    {
        public override string AreaName 
        {
            get 
            {
                return "MyArea";
            }
        }

        public override void RegisterArea(AreaRegistrationContext context) 
        {
            context.MapRoute(
                "myArea_default",
                "myArea/{controller}/{action}/{id}",
                new { action = "Index", id = UrlParameter.Optional },
                new { controller = new RegexRouteConstraint("[^api]")  },
                new string[] { "Sitecore.MVC.Areas.MyArea.Controllers" }
            );
        }
    }
}
}

Wednesday, July 6, 2016

Sitecore Powershell Extension Snippet- Create Custom User Defined Template Item



As I said everything in Sitecore is indeed an Item. If you understand the way Item is represented knowing sitecore as CMS will be more easy.

Use Case: I want to cut down my time to create user defined template by 50% rather than creating it from sitecore content editor or using sitecore rocks. I used Sitecore Powershell Extension to my rescue.

Download https://marketplace.sitecore.net/en/Modules/Sitecore_PowerShell_console.aspx

In my case, there are 4 steps involved while creating a user defined template.They are as follows:-


  • Create New Item using Template Item
  • Create Standard Value Item for this new item
  • Add Base Template which is already defined.
  • Add Common Renderings across template.

The above is very specific to scenario I had in my project. Somehow I wanted to play with SPE. I tried this and it helped me save 50% of the work effort.

Solution
Go to TDS pick up any item and you will see the internal representation of field or standard field variables with key and name. Use this to set values using SPE.

Important to remember , when you want to assign or set standard field values switch on RAW values option from Tab Menu->View-> click on checkbox to enable it,

Using these raw values we can assign the predefined base template and renderings.

You can checkout the code snippet in Gist for more details.

Code Snippet 1






Sample TDS Code : Lookup Standard Field Variables
----item----
version: 1
id: {F80C735D-CB69D16F9C4}
database: master
path: /sitecore/content/v/extrassage
parent: {F90C17F3-5CB-85961DC46E1F}
name: extras-usage
master: {00000000-0000-0000-0000-000000000000}
template: {5AD9859D54E9F61485B}
templatekey: Menu Item

----field----
field: {BA3F86A2779C1B5E}
name: __Sortorder
key: __sortorder
content-length: 3

500
----version----
language: en
version: 1
revision: c9a8172a-0d3ea5665ed1

----field----
field: {FF1A9AB0-84B35A2676}
name: Title
key: title
content-length: 19

Hope this is helpful.

Sunday, June 12, 2016

Run Powershell script from Gulp.js

Installation Requirement

  1. If your Visual Studio is 2013 or order install Task Runner Explorer - Download and install- https://visualstudiogallery.msdn.microsoft.com/8e1b4368-4afb-467a-bc13-9650572db708
  2. Node.js- Recommended for most users-Check this download link-https://nodejs.org/en/
 
  • Run from the cmd command from this solution or class library location.
  • Ensure you keep the gulp.js in location where the actions /events are required.
  • Run command below from Class Library or website folder: Npm I gulp -g

Change Environment variable path

Gulp .js can be run from Task Runner VS2015

var gulp = require("gulp");
var childProcess = require('child_process');

gulp.task('deploy-static-files', function (callback) {
    console.log("---------Start--------------------------");
    return childProcess.exec('Powershell.exe  -executionpolicy remotesigned -File  DeployStaticFiles.ps1', function (err, stdout, stderr) {
        console.log(stdout);
        console.log(stderr);
        if (err) console.log(err);

        console.log("Finished");
    });
})

Powershell script :Deploy Static file code

####----Copy files from source to destination-----
$publishPathDestination      =   "Some Path"
$scriptpathSource            = Split-Path $MyInvocation.MyCommand.Path
Copy-Item  "$scriptpath"     $publishPathDestination   -Recurse -Force;


Get description Attributes from Enum.

using System;
using System.ComponentModel;
using System.Linq;
using System.Reflection;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
         //Get Description
            Console.WriteLine(GetEnumDescription<MyEnum>(2));

            //Get Value
            Console.WriteLine(MyEnum.Hear);

            //Get Name
            Console.WriteLine(Enum.GetName(typeof(MyEnum), 1));

            //Get Enum Descriptions values
            var myEnumDescriptions =
                Enum.GetValues(typeof(MyEnum))
                    .Cast<MyEnum>()
                    .Select(n => new { ID = (int)n, Name = Enum.GetName(typeof(MyEnum), n), Description = GetEnumDescription(n) });

            //Get Name, Description, Value
            foreach (var item in myEnumDescriptions)
            {
                Console.WriteLine(item.Name);
            }

            //Iterate and fetch Description
            foreach (int iValues in Enum.GetValues(typeof(MyEnum)))
            {
                Console.WriteLine(GetEnumDescription <MyEnum>(iValues));
            }
        }

        public enum MyEnum
        {
            [Description("You can Walk")]
            Walk = 1,
            [Description("You can Talk")]
            Talk = 2,
            [Description("You can Hear")]
            Hear = 3
        }

        public static string GetEnumDescription(Enum value)
        {
            FieldInfo fi = value.GetType().GetField(value.ToString());

            DescriptionAttribute[] attributes =
                (DescriptionAttribute[])fi.GetCustomAttributes(
                    typeof(DescriptionAttribute),
                    false);

            if (attributes.Length > 0)
                return attributes[0].Description;
            else
                return value.ToString();
        }

        public static string GetEnumDescription <T>(int value)
        {
            return GetEnumDescription((Enum)(object)((T)(object)value));
        }
    }


}



Tuesday, May 31, 2016

My Powershell Code Snippets


1. Copy files from source to destination

####----Copy files from source to destination-----

$publishPathDestination      =   "Some Path"
$scriptpathSource            = Split-Path $MyInvocation.MyCommand.Path
Copy-Item  "$scriptpath"     $publishPathDestination   -Recurse -Force;

2. Duplicate and copy files

 ##---Duplicate and copy files
 
 $files="F1.pdf","F2.pdf"

 Foreach ($file in $files)
 {
       Copy-Item C:\DummyFiles\dummy.pdf -Destination C:\DummyFiles\Transfer\$file
 }


3. Sitecore Powershell extensions to create daily backup