A day with .Net

My day to day experince in .net

Archive for the ‘MVC’ Category

Return Json from a Web Api via HttpResponseMessage

Posted by vivekcek on June 26, 2016

This is a small tip to send json data through HttpResponseMessage.

First create the helper class in your Web Api Controller.

public class JsonContent : HttpContent
    {

        private readonly MemoryStream _Stream = new MemoryStream();
        public JsonContent(object value)
        {

            Headers.ContentType = new MediaTypeHeaderValue("application/json");
            var jw = new JsonTextWriter(new StreamWriter(_Stream));
            jw.Formatting = Formatting.Indented;
            var serializer = new JsonSerializer();
            serializer.Serialize(jw, value);
            jw.Flush();
            _Stream.Position = 0;

        }
        protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
        {
            return _Stream.CopyToAsync(stream);
        }

        protected override bool TryComputeLength(out long length)
        {
            length = _Stream.Length;
            return true;
        }
    }

Now try this in your Action method.

public HttpResponseMessage Delete(int id)
        {
            return new HttpResponseMessage()
            {
                Content = new JsonContent(new
                {
                    Name = "Vivek",
                    Address = "Address",
                    Message = "Any Message" //return exception
                })
            };
        }

Posted in MVC, Web API | Tagged: , , | 1 Comment »

Instance members of an ActionFilter attribute is not thread safe – MVC

Posted by vivekcek on June 26, 2016

I was trying to inject a dependency to my filter attribute via Ninject’s property injection.The injected instance was using a database connection too.
And one of the ajax polling call was hitting this attribute every 10 seconds.
Strange i got some thread concurrency issue and site went down.
Later i found that in MVC for each request a controller is created, but for each request the same instance of filter attribute is reused.

You can test this via putting break points in the constructor of controller and attribute.

1

2

Posted in MVC | Tagged: | Leave a Comment »

File upload and usability – Upload by a single click

Posted by vivekcek on June 26, 2016

Today i was just filing my tax via HRBlock India, and the experience was good.As you know for filing tax, you should upload your Form 16 docs to Hrblock.
They provide the below screen for uploading each document.Here you need to select each document and click the upload button, that is 2 click per upload.

Can we change this to single click, No i think because we may need to provide password for each file, if present.
So this screen is valid.

1

In some other sites , i have seen you have to do 2 mouse click for an upload.Normally developers design a file upload like below, a file browse input and upload button.

3

So how we can save one click, with just a single button click.

4

For that you can use bootstrap and jquery.

First add this style to your page.

<style type="text/css">
    .btn-file {
        position: relative;
        overflow: hidden;
    }

        .btn-file input[type=file] {
            position: absolute;
            top: 0;
            right: 0;
            min-width: 100%;
            min-height: 100%;
            font-size: 100px;
            text-align: right;
            filter: alpha(opacity=0);
            opacity: 0;
            outline: none;
            background: white;
            cursor: inherit;
            display: block;
        }
</style>

Place your input control via below code snippet.

<span class="btn btn-default btn-file">
    Upload Files <input type="file">
</span>

Use the below script to upload.

@section scripts
{
    <script type="text/javascript">
        $(document).ready(function () {
            $(document).on('change', '.btn-file :file', function () {
                var input = $(this);
                var files = input.get(0).files;
                if (files.length > 0) {
                    var data = new FormData();
                    for (i = 0; i < files.length; i++) {
                        data.append("file" + i, files[i]);
                    }
                    input.trigger("onclick");//Please keep this to fire the change event next time
  
                    $.ajax({
                        type: "POST",
                        url: "",
                        contentType: false,
                        processData: false,
                        data: data,
                        global: false,
                        success: function (response) {

                        },
                        error: function () {

                        }
                    });

                }
            });

            $(document).on('onclick', '.btn-file :file', function () {
                this.value = null;
            });
        });
    </script>
}

Posted in Jquery, MVC, SignalR | Tagged: , , , , | Leave a Comment »

SignalR in Web Farm or Web Garden Enviornment

Posted by vivekcek on May 23, 2016

I was trying to use SignalR 2 for one of my project and successfully implemented a progress bar using it.
Everything was working fine in our test server also. But fortunately i tested this SignalR 2 based progress bar in Web-garden mode of IIS,
Woww surprised nothing is working. Thanks God, because our production servers are load balanced Web Farm.

Any way found solution in Microsoft documentation. I will discuss that below.

Hope you have an understanding of SignalR.

1. Create an MVC 5 app.

2. Add Nuget package for SignalR.

Install-Package Microsoft.AspNet.SignalR

3.Now Paste the below code in your cshtml.

<input type="button" value="Submit" id="btnSubmit" />
<input type="hidden" id="connectionid" />

<div id="uploadModal"></div>

@section scripts
{
    <!--Reference the SignalR library. -->
    <script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script>
    <!--Reference the autogenerated SignalR hub script. -->
    <script src="~/signalr/hubs"></script>
    <script type="text/javascript">

        $(document).ready(function() {
            var con = $.connection.uploaderHub;
            $.connection.hub.start().done(function() {
                $("#connectionid").val($.connection.hub.id);

            }).fail(function(e) {
                alert('There was an error');
                console.error(e);
            });
            con.client.print = function() {
                $("#uploadModal").append("Vivek");
            };

            $("#btnSubmit").click(function() {

                var connectionid = $("#connectionid").val();
                var url = '@Url.Action("Test", "Home")';
                url = url + '?connectionid=' + connectionid;
                $.ajax({
                    type: "POST",
                    url: url,
                    dataType: 'json',
                    contentType: "application/json; charset=utf-8",
                    success: function(messages) {

                    },
                    error: function() {

                    }
                });

            });

        });
    </script>
}

4. Now create an action in your controller.

        [HttpPost]
        public ActionResult Test(string connectionid)
        {
            var hubContext = GlobalHost.ConnectionManager.GetHubContext<UploaderHub>();
            hubContext.Clients.Client(connectionid).print();
            return Json(new { Success = "True" });
        }

5. Create a SignalR hub.

using Microsoft.AspNet.SignalR;

namespace SignalR.Controllers
{
    public  class UploaderHub:Hub
    {

    }
}

6. In your OWIN Startup.cs add the code below.

using Microsoft.Owin;
using Owin;

[assembly: OwinStartupAttribute(typeof(SignalR.Startup))]
namespace SignalR
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
            ConfigureAuth(app);
        }
    }
}

Deploy this to IIS and click submit button, Which will print the text defined in client side print method.

Now increase the worker process count in your application pool to 5, Also set processor affinity true.
Try the same after some refresh, You will found the messaging is not working.

1

To Solve this you can use another SignalR package for SQL Server

Install-Package Microsoft.AspNet.SignalR.SqlServer -Version 2.2.0

Then update your OWIN Startup.cs add this.

using Microsoft.AspNet.SignalR;
using Microsoft.Owin;
using Owin;

[assembly: OwinStartupAttribute(typeof(SignalR.Startup))]
namespace SignalR
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            string sqlConnectionString = "Connecton string to your SQL DB";
            GlobalHost.DependencyResolver.UseSqlServer(sqlConnectionString);
            app.MapSignalR();
            ConfigureAuth(app);
        }
    }
}

Which will create some tables, in the database you specified in your connection string.
And now debug…

Posted in AJAX, MVC, SignalR | Tagged: , , , | 2 Comments »

Injecting different implementation of same interface via Ninject – Contextual Injection

Posted by vivekcek on May 8, 2016

Hi Guys,

I was just working on combining a Factory Method Pattern with Strategy Pattern. During this i came across contextual injection.
Please refer my old post.
Strategy Pattern
Factory Method Design Pattern

I have a common Factory interface, But i want to use separate implementation of this same interface in my two controllers.
I am always using Ninject for all of my MVC app’s. Then I found Ninject have feature for Contextual injection.

Hope You know how to use Ninject, else refer my blog.
Using Ninject

So come to the point.

This is my interface.

    public interface IMyInterface
    {
        void add();
    }

This is my First Implementation.

 public class MyImplementation1 : IMyInterface
    {
        public void add()
        {
            throw new NotImplementedException();
        }
    }

This is my second implementation.

 public class MyImplementation2 : IMyInterface
    {
        public void add()
        {
            throw new NotImplementedException();
        }
    }

The below code can be used for contextual mapping in Ninject

            kernel.Bind<IMyInterface>().To<MyImplementation1>().Named("Implementation1");
            kernel.Bind<IMyInterface>().To<MyImplementation2>().Named("Implementation2");

Now in my First Controller, i can use first implementation.

        IMyInterface _myImpe = null;
        public HomeController([Named("Implementation1")] IMyInterface myImpe)
        {
            _myImpe = myImpe;
        }

In the Second controller.

        IMyInterface _myImpe = null;
        public AccountController([Named("Implementation2")] IMyInterface myImpe)
        {
            _myImpe = myImpe;
        }

For property injection use this snippet.

        [Inject, Named("Implementation2")]
        public IMyInterface Foo { get; set; }

Posted in MVC, Ninject | Tagged: , , , | Leave a Comment »

Web API inside an MVC Area

Posted by vivekcek on May 7, 2016

This is strange thing, i faced when added a Web Api controller inside an area of my production code.
I was using the defualt Web Api route pattern in WebApiConfig.cs

config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);

Unfortunately when i tried to access the path via Jquery Ajax, I got the path not found exception.

This was the path i tried.
http://localhost:56109/api/MySecond

Ok, so i thought as my API controller is under an Area, i should try this way.

http://localhost:56109/api/MyArea/MySecond

Ooops!! still path not found, hmm. I added below code in my AreaRegistraion.Cs file.
Don’t forget to add refrence of “System.Web.Http”

context.Routes.MapHttpRoute(
"FileUpload",
"MyArea/api/{controller}/{id}",
new { AreaName = "MyArea", id = UrlParameter.Optional }
);

Wow now this path is working fine “http://localhost:56109/api/MyArea/MySecond

NB: This was experience in a production app developed with MVC 5 and VS 2013, Anyway i was not able to reproduce this in VS 2015.
As far as my understanding Web Api controllers and routing is independent of MVC Area.

Posted in MVC, Web API | Tagged: , , | Leave a Comment »

JavaScript Logging in ASP.NET MVC – Jsnlog and elmah

Posted by vivekcek on July 25, 2015

Hi Guys in this post i will show you, how you can log javascipt erros in your asp.net mvc applications.

First of all, let me tell you the tools.

1. Visual Studio 2013
2. ASP.NET MVC 4
4. Elmah.mvc
5. Jsnlog.elmah
6. SQL Server 2008

So we can start

1. Create an MVC application.

2. Got to Nugget and add Elmah.MVC, Please note i using elmah’s mvc package

1

3. Now go to elmah site and download sql scripts for elmah

2

4. Create a database named Logging and apply the downloaded script.

3
5. Go to web.config and add connection string for elmah

4

6.Configure elmah in web.config by adding this

 <elmah>
    <errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="elmah" />
     <security allowRemoteAccess="false" />
  </elmah>

5

7. Great now thorw an exception from your home controller

6

8. Go to elmah, if you saw this screen, we are good, elmah is configured correctly
7

9. Again back to Nugget and add Jsnlog for elmah

8

10. Go to your _Layout.csftml and add this at top

@Html.Raw(JSNLog.JavascriptLogging.Configure())
    <script type="text/javascript">
        window.onerror = function (errorMsg, url, lineNumber, column, errorObj) {

            // Send object with all data to server side log, using severity fatal,
            // from logger "onerrorLogger"
            JL("onerrorLogger").fatalException({
                "msg": "Exception!",
                "errorMsg": errorMsg, "url": url,
                "line number": lineNumber, "column": column
            }, errorObj);

            // Tell browser to run its own error handler as well
            return false;
        }
    </script>

9

11. Make some javascript error in index.cshtml

@section scripts{
    <script type="text/javascript">
        JL().info("This is a log message");
        xyz;
    </script>

}

10

12. Go to elmah and watch this

11

Posted in javascript, MVC | Tagged: , , , , , | Leave a Comment »

One DbContext per request in an Asp.net MVC project by dependency injection and Ninject.

Posted by vivekcek on November 14, 2014

You know the entity framework dbcontext is not thread safe.

One of my friend faced an issue regarding the data mismatch happening in his MVC app.
After some inspection i learned that he was using a singleton dbcontext for his application.

Uhhhhhh! buddy static dbcontext and singleton dbcontext will screw you, why?

The Entity Framework data context object caches all of its data for as long as it exists. This means that it gets its data once from the database, then every time you request that data it returns it from its own cache. To function properly EF data contexts need to be created and destroyed with each page request.
Ok, So how we can achieve this. The Unit Of Work pattern with dependency inject can solve this well.
But he was not using Unit Of Work, aaah!!shit!! What to do??

Here comes the Ninject’s InRequestScope(), Which can spawn a new dbcontext instance per Http request, great!! i wana try.

If you don’t know how to use Ninject refer net.

1. Create an MVC app.

2. From Nugget use Ninject for MVC (Ninject.MVC3, Ninject.MVC4, Ninject.MVC5 etc..)

3. Let EmployeeDbContect be your dbcontect class.

4. Prepare your controller for dependency injection.

 public class HomeController : Controller
 {
 private EmployeeDbContext _context;

 public HomeController(EmployeeDbContext context)
 {
 _context = context;
 }

 public ActionResult Index()
 {
 return View();
 }

 }

5. Now in App_Start folder open NinjectWebCommon.cs. In CreateKernel method write these statements.

DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
kernel.Bind<EmployeeDbContext>().ToSelf().InRequestScope();

Posted in MVC | Tagged: , , , | Leave a Comment »

Caching in ASP.NET MVC with Repository Pattern and WCF

Posted by vivekcek on June 25, 2014

In this post i will show you, how to implement caching in an asp.net mvc application.
This MVC application use repository pattern and consumes a WCF service.

1. Define an interface for our caching provider.

 public interface ICacheProvider
    {
        object Get(string key);
        void Set(string key, object data, int cacheTime);
        bool IsSet(string key);
        void Invalidate(string key);

    }

2. Implement this interface, dont forget to add reference for System.Runtime.Caching

 public class DefaultCacheProvider : ICacheProvider
    {
        private ObjectCache Cache { get { return MemoryCache.Default; } }

        public object Get(string key)
        {
            return Cache[key];
        }

        public void Set(string key, object data, int cacheTime)
        {
            CacheItemPolicy policy = new CacheItemPolicy();
            policy.AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(cacheTime);

            Cache.Add(new CacheItem(key, data), policy);
        }

        public bool IsSet(string key)
        {
            return (Cache[key] != null);
        }

        public void Invalidate(string key)
        {
            Cache.Remove(key);
        }
    }

3. In your repository add this code.

public class DVDRepository : IRepository
    {
        protected DVDStoreService.DVDServiceClient serviceClient;
        protected ICacheProvider cache;
        public DVDRepository(DVDStoreService.DVDServiceClient client, ICacheProvider cache)
        {
            if (client == null)
            {
                throw new ArgumentNullException("client");
            }
            serviceClient = client;
            this.cache = cache;
        }

        public List<DVDStoreService.Movie> GetAll()
        {
            List<DVDStoreService.Movie> movies = cache.Get("movies") as List<DVDStoreService.Movie>;
            if (movies == null)
            {
                movies = serviceClient.GetAllData().ToList();
                cache.Set("movies", movies, 60);
            }
            return movies;
        }
      }

Posted in MVC, WCF | Tagged: , , | Leave a Comment »

File upload with ASP.NET MVC and Jquery Form Plugin.

Posted by vivekcek on April 21, 2014

In this post, i will show you how to upload a file without a full postback using Jquery Form Plugin.
Jquery form plugin use ajax to upload the file. This technique will be more helpful when you need to upload file from a modal partial view.

Refer these scripts.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.js"></script>
<script src="http://malsup.github.com/jquery.form.js"></script>

Create a file input and a submit button.

@using (Html.BeginForm("Save", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    
    <input type="file" name="myfile"><br>
    <input type="submit" value="Upload File to Server">
}

Now create some div’s for progress bar and status

<div class="progress">
    <div class="bar"></div>
    <div class="percent">0%</div>
</div>
<div id="status"></div>

Now include this script in your view

<script>
    (function () {

        var bar = $('.bar');
        var percent = $('.percent');
        var status = $('#status');

        $('form').ajaxForm({
            beforeSend: function () {
                status.empty();
                var percentVal = '0%';
                bar.width(percentVal)
                percent.html(percentVal);
            },
            uploadProgress: function (event, position, total, percentComplete) {
                var percentVal = percentComplete + '%';
                bar.width(percentVal)
                percent.html(percentVal);
            },
            success: function () {
                var percentVal = '100%';
                bar.width(percentVal)
                percent.html(percentVal);
            },
            complete: function (xhr) {
                status.html(xhr.responseText);
            }
        });

    })();
</script>

Now write a save method in your controller

[HttpPost]
 public ActionResult Save(HttpPostedFileBase myfile)
      {
         return RedirectToAction("Index");
      }

Posted in MVC | Tagged: , , , | 1 Comment »