About Hasmukh patel

My Photo
Harrow, London, United Kingdom
Dot-Net developer with expertise in Web, WPF, Win-form applications. Have worked on Asp.net,mvc , WPF and Win-forms projects in c#.net language having Sql-Server/Oracle as database with service oriented architecture using test driven development. Having complete knowledge of SDLC and have successfully worked and implemented it on projects.

Knockout - Web Controls Extensions (MVC 4+)


Knockout - Web Controls Extensions for MVC 4 and above

MVC 4 Controls Extensions contains extension methods for standard html & Knockout controls like editable generic Grid, dropdown, textbox, radiobutton & checkbox controls.

To install MVC 4 Controls Extensions, run the following command in the Package Manager Console

PM>Install-Package MVCControlsExtensions

source code available at Github


Controls Extensions

  • @Html.KOTextBoxFor(model => model.Name)
  • @Html.KODisplayFor(model => model.Name)
  • @Html.KOCheckBoxFor(x=>x.IsActive)
  • @Html.KODateTextBoxFor(model => model.Date)
  • @Html.KODropDownListFor(model => model.Id, Model.SelectedList)
  • @Html.KOPasswordFor(model => model.Password)
  • @Html.KOForeEachBindingFor(model => model.Items)
  • @Html.KOPartialFor(model => model.Address,"_address")
    

Grid Example

Editable KO grid

<div class="editor-field">
@Html.KOGridFor(model => model.NewsList,
    col => col.AddKOTextColumnFor(item => item.Summary, options: new KOBindingOptions { Enable = "canEdit()" }),
    col => col.AddKOTextColumnFor(item => item.Description),
    col => col.AddKODateTextColumnFor(item => item.PublishedOn),
    col => col.AddKOTextColumnFor(item => item.Id),
    col => col.AddColumn("X""<input type=\"button\" value=\"Add\" onclick=\"AddNewRow(this)\" />"),
    col => col.AddKODeleteButtonColumn("X""Add",
        options: new KOBindingOptions { Click = "$parent.removeNews" },
        headerOptions: new KOBindingOptions { Click = "$data.addNews" }))
@Html.ValidationMessageFor(model => model.NewsList)
</div>

Vertical Editable Grid

<div>
    @Html.VerticalGridFor(x => x.NewsList,
        col => col.AddColumnFor(x => x.Description),
        col => col.AddColumnFor(x => x.PublishedOn),
        col => col.AddColumnFor(x => x.Summary))
</div>

Create view using Knockout Scaffold template


Inject HttpContext Services

Inject HttpContext (System.Web.HttpContext.Current) as a Service


When you are dealing with HttpContext.Current, it is very hard to write unittests so better to split into multiple services and inject as and when required.
HttpContext.Current can split into following services:

  • ItemService
  • CacheService
  • SessionService
  • RequestService

Example code

Intrfaces

public interface IHttpContextItemServcie
{
    T GetItem<T>(object key);
}
 
public interface IHttpContextCacheServcie
{
    T GetItem<T>(string key);
 
    void SetItem<T>(string key, T value);
 
}
 
public interface ICacheDataProvider<TV>
{
    TV GetValue(string key, Func<TV> defaultValueFactory = null);
    void SetValue(string key, TV value);
}


implementation

using System.Web;
using System.Web.Caching;
 
public abstract class HttpContextServcie
{
    protected HttpContext Context { get { return HttpContext.Current; } }
}
 
public class HttpContextItemServcie : HttpContextServcieIHttpContextItemServcie
{
    public T GetItem<T>(object key)
    {
        return (T)Context.Items[key];
    }
}
 
public abstract class CacheDataProviderBase : HttpContextServcie
{
    protected object GetValue(string key)
    {
        return Context.Cache[key];
    }
 
    protected void SetValue(string key, object value)
    {
        Context.Cache.Insert(key, value, Dependencies, AbsoluteExpiration, SlidingExpiration);
    }
 
    protected object RemoveValue(string key)
    {
        return Context.Cache.Remove(key);
    }
 
    protected virtual CacheDependency Dependencies
    {
        get { return null; }
    }
 
    protected virtual DateTime AbsoluteExpiration
    {
        get { return DateTime.Now.AddMinutes(30); }
    }
 
    protected virtual TimeSpan SlidingExpiration
    {
        get { return Cache.NoSlidingExpiration; }
    }
}
 
 
public class HttpContextCacheServcie : CacheDataProviderBaseIHttpContextCacheServcie
{
    public T GetItem<T>(string key)
    {
        return (T)GetValue(key);
    }
 
    public void SetItem<T>(string key, T value)
    {
        SetValue(key, value);
    }
}
 
 
public abstract class CacheDataProviderBase<TSTV> : HttpContextCacheServcieICacheDataProvider<TV>
{
    protected readonly Lazy<TS> Service = new Lazy<TS>(() => DependencyResolver.Current.Resolve<TS>());

 
    protected string GetCombinedKey(string key)
    {
        return string.Format("{0}_{1}", ProviderKey, key);
    }
 
    public virtual TV GetValue(string key, Func<TV> defaultValueFactory = null)
    {
        var combinedKey = GetCombinedKey(key);
        var cachedvalue = base.GetValue(combinedKey);
 
        if (cachedvalue == null && defaultValueFactory != null)
        {
            var newValue = defaultValueFactory();
            base.SetValue(combinedKey, newValue);
            return newValue;
        }
 
        return (TV)cachedvalue;
    }
 
    public virtual void SetValue(string key, TV value)
    {
        base.SetValue(GetCombinedKey(key), value);
    }
 
    protected abstract string ProviderKey { get; }
 
}

customise Cache Data Provider


public class CustomCacheDataProvider : CacheDataProviderBase<IMyServiceMyData>
{
    protected override string ProviderKey { get { return "Uniqe name"; } }
 
    public override MyData GetValue(string key, Func<MyData> defaultValueFactory = null)
    {
        defaultValueFactory = defaultValueFactory ?? (() => Service.Value.GetData(key));
        return base.GetValue(key, defaultValueFactory);
    }
}
 
public class MyData
{
}
 
public interface IMyService
{
    MyData GetData(string id);
}
//implement your service and inject in mvc

Source available at Github