Ehsan Ghanbari

Experience, DotNet, Solutions

How to use PagedList In asp.net MVC

PagedList.Mvc is one of many good paging and sorting packages for ASP.NET MVC, in the below simple example I'm gonna implement it for content (posts) of a blog post, install the PagedList.MVC via Nuget and take a look at this code. This is an action which returns blog posts:

 

       public ActionResult List(int? page)
        {
            var posts = _blogService.GetAllBlogPosts();
            var pageNumber = page ?? 1;
            var onePageOfPosts = posts.ToPagedList(pageNumber, 10);
            ViewBag.OnePageOfPosts = onePageOfPosts;
            return View(posts);
        }

 

 I just defined the OnePageOfPosts  ViewBag and onePageOfPosts.  now in the view, you have to add a line of code:

 

@using PagedList
@using PagedList.Mvc;
@model IEnumerable<BlogViewModel>
@{
      ViewBag.Title = "List";
   }
@foreach (var item in Model)
 {
           @Html.ActionLink(item.Title, "Post", "Blog", new { postId = item.PostId, urlSlug = item.UrlSlug }, null)
           @Html.DisplayTextFor(blog => item.Body)
  }

@Html.PagedListPager((IPagedList)ViewBag.OnePageOfPosts, page => Url.Action("List", new { page }) )

 

if you run this piece of code, you should have something like this in the output:

 

<< First < Previous 1 2 3 4 5 … Next > Last >> 

 



Redis as a cache server

Although Redis is much more than a cache, But it's possible to use as cache server especially in distributed applications. Redis lets you operate on the values and it's just a key-value pair in-memory database.

To getting started, get the latest version of Redis from here and install in your windows machine (Server) by instruction and run it in your services. Redis runs in your server machine (you can have Redis server and client in one machine which could be your client development machine) and you call it from a client by a library. Now to work with Redis in a server you need to get stack exchange via Nuget and implement your methods provided by it.

Note: You can read all descriptions and instructions of stack exchange Redis in Github.

public class RedisCacheManager

    {

        private readonly ConnectionMultiplexer _connectionMultiplexer;

        private readonly IDatabase _dataBase;

        private IServer _server;



        private static Lazy<ConfigurationOptions> configurations = new Lazy<ConfigurationOptions>(() =>

        {

            var configuration = new ConfigurationOptions();

            configuration.EndPoints.Add("192.168.110.149:6421");

            configuration.ConnectTimeout = 100000;

            configuration.SyncTimeout = 100000;

            configuration.AllowAdmin = true;

            configuration.Password = "skdfenr4";

            return configuration;

        });



        public RedisCacheManager()

        {

            _connectionMultiplexer = ConnectionMultiplexer.Connect(configurations.Value);

            _dataBase = _connectionMultiplexer.GetDatabase();

            var endpoints = _connectionMultiplexer.GetEndPoints();

            _server = _connectionMultiplexer.GetServer(endpoints.First());

        }



        public object Retrieve(string key)

        {

            var rValue = _dataBase.StringGet(key);

            if (!rValue.HasValue)

                return rValue;

            return JsonHelper.Deserialize<object>(rValue);

        }



        public T Retrieve<T>(string key)

        {

            var rValue = _dataBase.StringGet(key);

            if (!rValue.HasValue)

                return JsonHelper.Deserialize<T>(null);

            return JsonHelper.Deserialize<T>(rValue);

        }



        public T Retrieve<T>(string key, int pageIndex)

        {

            var rValue = _dataBase.StringGet(key);

            if (!rValue.HasValue)

                return JsonHelper.Deserialize<T>(null);

            return JsonHelper.Deserialize<T>(rValue);

        }



        public bool Contain(string key)

        {

            return _dataBase.KeyExists(key);

        }



        public void Store(string key, object value)

        {

            if (value == null)

                return;



            var entryBytes = JsonHelper.Serialize(value);

            _dataBase.StringSet(key, entryBytes);

        }



        public void Store(string key, object value, int cacheTime)

        {

            if (value == null)

                return;



            var entryBytes = JsonHelper.Serialize(value);

            var expiresIn = TimeSpan.FromMinutes(cacheTime);



            _dataBase.StringSet(key, entryBytes, expiresIn);

        }



        public void Remove(string key)

        {

            _dataBase.KeyDelete(key);

        }



        public void Clear()

        {

            var endpoints = _connectionMultiplexer.GetEndPoints(true);

            foreach (var endpoint in endpoints)

            {

                var server = _connectionMultiplexer.GetServer(endpoint);

                server.FlushAllDatabases();

            }

        }



        private static byte[] Serialize(object item)

        {

            var jsonString = JsonConvert.SerializeObject(item);

            return Encoding.UTF8.GetBytes(jsonString);

        }



        private static T Deserialize<T>(byte[] serializedObjectValue)

        {

            if (serializedObjectValue == null)

                return default(T);



            var jsonString = Encoding.UTF8.GetString(serializedObjectValue);

            return JsonConvert.DeserializeObject<T>(jsonString);

        }

    }

 

I Just implemented the most used methods in a caching system, you can implement your own based on your needs. As you see I created configurations with some initializing. for example EndPoints(you can get it from the server that Redis is running on) and password (for making the connection between client and server secure).  In the constructor of the class, you need to connect to Redis server via ConnectionMultiplexer and get the database to work with.



Domain driven design VS model driven architecture

Domain Driven design(DDDesign) is not the same Model Driven Architecture(MDA). Although The root of both DDDesign and MDA is the same and it is Model Driven Engineering and also both of them aim to solve the problem of converting a 'pure' problem domain model into a full software system. But there are some differences.

Domain Driven Design concentrates on Modeling and solving the Domain problem by Capturing the model from the Ubiquitous language. it is about modeling a domain of knowledge with a high level of abstraction and its focuses are on domain logic and tries to keep the design as much close to the real world. In DDDesign you create the model with the Ubiquitous language so you should understand the business without any technical issues. In another side, model forms the ubiquitous language of DDDesign which explains the domain in a simple form and it's kinda a backbone of DDDesign.

But Model-driven architecture is an approach to building the model of the system. As I mentioned MDA is a kind of domain engineering too. A model is just some taken classes, methods and ... from the problem domain. MDA provides you to use multiple standards such as UML. 

 

but you know it doesn't stop there, I don't know more than these two paragraphs about differences of DDD and MDA! please let me know more about these two architectures and differences by comments, thanks...



What's the DDD-lite?

Based on Vaughn Vernon 's definition, "DDD-Lite is a means of picking and choosing a subset of the DDD tactical patterns, but without giving full attention to discovering, capturing, and enhancing the Ubiquitous Language." most of the DDD-like approaches are not really DDD! If you don’t have bounded contexts so Ubiquitous language(UL) doesn't mean anything and if you have no UL, you won't have business rules.

In DDD, you should concentrate on a domain model and establish a ubiquitous language and use the patterns of DDD. But most of the cases your application is not complex and big enough to apply the whole DDD approach. but for more and different reasons you are going to use DDD patterns. For example when your application doesn't have any complex and different scenarios to separate them as bounded contexts or SubDomains - and you just embrace technical tools, concepts and patterns of DDD like simple entities, services, repositories, aggregates. In these cases, you can use patterns of DDD within your code and call it "DDD-lite".

I started a project about 10 days ago, it's so interesting that I just read about DDD-lite yesterday; but when I designed the architecture of the project, as I'm really interested in DDD I assigned entities as Aggregate and used the repository and layerSupertype patterns, Repository and Service layers. But I don't have any bounded context, value object, subdomain, UL, Domain Service or context map in this project. I've approximately finished the project, I'm gonna to describe the architecture of the project in a few days after hosting in this tag of my blog with "statos" title.

As a usual it's my pleasure you to correct my mistakes, thanks

 

 



Multiple submit buttons in asp.net MVC

In asp.net MVC you can submit a form by @using(Html.BeginForm()). You can Post the model you have bound via this operation and command the beginning form to post to a Post action: 

@using(Html.BeginForm("Create","FooController")).

Now if you have more than one submit button to send the page content to different post action, there are few ways: one of them is to post the content to a specific action and then decide in it to redirect which action:

 Razor:

<input type="submit" value="Field1" name="submitButton"  />

<input type="submit" value="Field2" name="submitButton"  />

 

Controller:

         public ActionResult SpecificOne(DTO dTO, string submitButton)

         {

                switch (submitButton)

                {

                    case "Field1":

                            return RedirectToAction("FirstCreate")

                    case "Field2":

                              return RedirectToAction("SecondCreate")

                 }

          }

 

But the way that I like it more is to use the attribute in post actions, this attribute would be like this:

   [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]

    public class HttpParamActionAttribute : ActionNameSelectorAttribute

    {

        public string Name { get; set; }



        public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)

        {

            return controllerContext.HttpContext.Request[Name] != null;

        }

    }

 

 

Now in your razor view, you should give a name to your buttons (names should be the same as your target actions) :

@model DTO 

@using(Html.beginForm(null, null))

{

   <button type="submit" name="FirstCreate" >First</button>

   <button type="submit" name="SecondCreate" >Second</button>        

}

And about the actions you should use the mentioned attribute and give the button name property:

        [HttpPost]

        [HttpParamAction(Name = "FirstCreate")]

        public ActionResult FirstCreate()

        {

            return View();

        }





        [HttpPost]

        [HttpParamAction(Name = "FirstCreate")]

        public ActionResult SecondCreate()

        {

            return View();

        }

 

Good luck!



About Me

Ehsan Ghanbari

Hi! my name is Ehsan. I'm a developer, passionate technologist, and fan of clean code. I'm interested in enterprise and large-scale applications architecture and design patterns and I'm spending a lot of my time on architecture subject. Since 2008, I've been as a developer for companies and organizations and I've been focusing on Microsoft ecosystem all the time. During the&nb Read More

Post Tags
Pending Blog Posts
Strategic design
Factory Pattern
time out pattern in ajax
Selectors in Jquery
using Log4net in asp.net MVC4
How to use PagedList In asp.net MVC
Redis as a cache server
Domain driven design VS model driven architecture
What's the DDD-lite?
Multiple submit buttons in asp.net MVC