Ask your technical questions on forums or here :
ASP.NET or MVC | C# | Windows Phone
Microsoft Technology Journals by Abhimanyu K Vatsa
HOME ABOUT RAZOR BOOK SPEAKING MVC ASP.NET JQUERY VIDEOS EBOOK ARCHIVE
Showing posts with label MVC. Show all posts
Showing posts with label MVC. Show all posts

4 Dec 2016

Slug URL in MVC

Creating a human friendly URL is one of the important goal in content management system. Recently one developer asked me this question. Like he always sees 'id' in URL in MVC application which is not human friendly. He mentioned stack-overflow example when explaining issue to me, so let’s discuss about this.

Open stack-overflow page

you will be redirected to

Notice the last part in the query, this is nothing but a slug that is being added in URL all the time. Technically both URL maps to same resource. And in URL number '40956081' is unique identifier.

I hope you know Stack-Overflow is also build using ASP.NET MVC. Let's build similar slug and similar behavior in your MVC application.

First you need to configure your route as give below:

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Question_Default",
                url: "question/{id}/{slug}",
                defaults: new { controller = "home", action = "question", id = UrlParameter.Optional, slug = UrlParameter.Optional }
            );

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "home", action = "index", id = UrlParameter.Optional }
            );
        }

Now you need to write slug redirect logic in MVC action or you can create action filter if you want this to be reusable.

        public ActionResult Question(int id, string slug)
        {
            // call database table to get question based on input 'id'
            // 'id' is primary key in database table
            // depending on unique slug all the time is not good idea
            // so, let's keep 'id' primary key and keep it using
            var question = QuestionExtension.GetQuestion(id);

            // check if database returned no question
            if (question == null)
                return Redirect("~/error/noquestion");

            // redirect on slug based url here only
            // or you can create action filter so that it works everywhere in your application
            if (string.IsNullOrEmpty(slug))
            {
                slug = question.Slug;
                return RedirectToRoute("Question_Default", new { id = id, slug = slug });
            }

            return View(question);
        }

And that's it, you are good to test this. I have uploaded this project on GitHub for you in case you would like to test my code.

Hope this helps.

31 Aug 2016

Azure Media Service Encoding with custom presets

In this post you will learn how to use custom preset for Azure Media Service Encoding. But before that let's look at a case study or issue which I faced.

Introduction

When I uploaded a 55.5 MB mp4 file and encoded with "H264AdaptiveBitrateMP4Set720p" encoder preset, I received following output files:



















Look into green rectangular highlighted video files in the image, this looks good according to input file size. But if you look at red rectangular highlighted video files, these are *improved* files for adaptive streaming, which looks useless if you compare with my example "a dark line on my face in video can't be removed by system automatically...make sense". Here I'm trying to understand Azure Media Services encoding permutations but increasing file size 2-3 times larger than input file is never a acceptable deal.

Why I should pay more for bandwidth and storage on these large files, how I convince my clients?

On this issue I thought to understand this from community so I posted this here, but I'm still not convinced with answer.

Note: What are exact reasons encoder increases the file size, if you come to know please share with me too?

Is there any way I can define not to create such files when scheduling encoding?

Yes, we can use custom preset file and send it with encoding request to Azure Media Service. Let's see how it works in the code:

//// XML Preset
string name = "UploadedVideo-" + Guid.NewGuid().ToString();
IJob job = context.Jobs.Create(name);
IMediaProcessor processor = GetLatestMediaProcessorByName("Media Encoder Standard", context);
string configuration = System.IO.File.ReadAllText(HttpContext.Server.MapPath("~/MediaServicesCustomPreset.xml"));
ITask task = job.Tasks.AddNew(name + "- encoding task", processor, configuration, TaskOptions.None);
task.InputAssets.Add(inputAsset);
task.OutputAssets.AddNew(name + "-Adaptive-Bitrate-MP4", AssetCreationOptions.None);
job.Submit();
IAsset encodedOutputAsset = job.OutputMediaAssets[0];
string smoothStreamingUri = PublishAssetGetURLs(encodedOutputAsset, fileName);
string assetDetails = "MediaServiceFileName:" + encodedOutputAsset.Name + ", MediaServiceContainerUri:" + encodedOutputAsset.Uri + ", AssetId:" + encodedOutputAsset.Id;

Check code in repository here.

Notice blue highlighted code, that's what I added to send custom preset file with encoding request. I will be using xml preset file, you can use json file too. Let's look at the xml file now.

<?xml version="1.0" encoding="utf-16"?>
<Preset xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Version="1.0" xmlns="http://www.windowsazure.com/media/encoding/Preset/2014/03">
  <Encoding>
    <H264Video>
      <KeyFrameInterval>00:00:02</KeyFrameInterval>
      <H264Layers>
        <H264Layer>
          <Bitrate>1500</Bitrate>
          <Width>960</Width>
          <Height>540</Height>
          <FrameRate>0/1</FrameRate>
          <Profile>Auto</Profile>
          <Level>auto</Level>
          <BFrames>3</BFrames>
          <ReferenceFrames>3</ReferenceFrames>
          <Slices>0</Slices>
          <AdaptiveBFrame>true</AdaptiveBFrame>
          <EntropyMode>Cabac</EntropyMode>
          <BufferWindow>00:00:05</BufferWindow>
          <MaxBitrate>1500</MaxBitrate>
        </H264Layer>
        <H264Layer>
          <Bitrate>1000</Bitrate>
          <Width>640</Width>
          <Height>360</Height>
          <FrameRate>0/1</FrameRate>
          <Profile>Auto</Profile>
          <Level>auto</Level>
          <BFrames>3</BFrames>
          <ReferenceFrames>3</ReferenceFrames>
          <Slices>0</Slices>
          <AdaptiveBFrame>true</AdaptiveBFrame>
          <EntropyMode>Cabac</EntropyMode>
          <BufferWindow>00:00:05</BufferWindow>
          <MaxBitrate>1000</MaxBitrate>
        </H264Layer>
        <H264Layer>
          <Bitrate>650</Bitrate>
          <Width>640</Width>
          <Height>360</Height>
          <FrameRate>0/1</FrameRate>
          <Profile>Auto</Profile>
          <Level>auto</Level>
          <BFrames>3</BFrames>
          <ReferenceFrames>3</ReferenceFrames>
          <Slices>0</Slices>
          <AdaptiveBFrame>true</AdaptiveBFrame>
          <EntropyMode>Cabac</EntropyMode>
          <BufferWindow>00:00:05</BufferWindow>
          <MaxBitrate>650</MaxBitrate>
        </H264Layer>
        <H264Layer>
          <Bitrate>400</Bitrate>
          <Width>320</Width>
          <Height>180</Height>
          <FrameRate>0/1</FrameRate>
          <Profile>Auto</Profile>
          <Level>auto</Level>
          <BFrames>3</BFrames>
          <ReferenceFrames>3</ReferenceFrames>
          <Slices>0</Slices>
          <AdaptiveBFrame>true</AdaptiveBFrame>
          <EntropyMode>Cabac</EntropyMode>
          <BufferWindow>00:00:05</BufferWindow>
          <MaxBitrate>400</MaxBitrate>
        </H264Layer>
      </H264Layers>
      <Chapters />
    </H264Video>
    <AACAudio>
      <Profile>AACLC</Profile>
      <Channels>2</Channels>
      <SamplingRate>48000</SamplingRate>
      <Bitrate>128</Bitrate>
    </AACAudio>
  </Encoding>
  <Outputs>
    <Output FileName="{Basename}_{Width}x{Height}_{VideoBitrate}.mp4">
      <MP4Format />
    </Output>
  </Outputs>
</Preset>

Check code in repository here.

If we do not pass custom preset file to Azure Media Service, then they use their default preset file which has higher bitrates and they don't have better logic to check input file bitrate and based on this decide new bitrates, this is what I understood.

So, I removed higher bitrate encoding from my preset file and this does the work. This has one disadvantage is that, any superb video quality will be loosed because preset is hardcoded for every video file. But, at-least now I have opportunity to write this bitrate dynamically based on video being uploaded through our service. And then send this new bitrate to Azure Media Services. Check the issue log here.

Hope this helps.

17 Jun 2016

Caching in MVC with Donut Caching - excluding caching login

The main purpose of using caching is to dramatically improve the performance of your application. This is nothing but output caching that means whatever you see is cached, and exact similar things is display to everyone.

I recommend you to read Output Caching in MVC post before you read here, because you should be very careful when using any caching mechanism. Or, if you already know output caching, keep reading here only.

Biggest problem you face

If you display user login status on page which you want to cache, then you need to be careful. With output cache attribute [OutputCache(....)] caches everything on page and it will not exclude caching of some portion like login status.

In the situation, the best caching library you should use is Donut Caching (aka Donut Output Caching). Let’s understand its uses.

Using Donut Caching

The best way to add donut caching to your MVC project is to use the NuGet package. From within Visual Studio, select Tools | Library Package Manager and then choose either Package Manager Console or Manage NuGet Packages. Via the console, just type install-package MvcDonutCaching and hit return. From the GUI, just search for MvcDonutCaching and click the install button.

Excluding from being cached

The package adds several overloads to the built-in Html.Action HTML helper. The extra parameter in each overload is named excludeFromParentCache. Set this to true for any action that should not be cached, or should have a different cache duration from the rest of the page.

@Html.Action("Login", "Account", true)

Here Login is a method inside Account controller, you should define this method like:

public class AccountController : Controller
{
    [ChildActionOnly]
    public ActionResult Login()
    {
        return PartialView("_LoginPartial");
    }
}

Cache rest of the page

The package also include a DonutOutputCacheAttribute to be used in place of the built-in OutputCacheAttribute. This attribute is typically placed on every controller action that needs be be cached.

You can either specify a fixed duration:

[DonutOutputCache(Duration = "300")]
public ActionResult Index()
{
    return View();
}

Or, use a cache profile:

[DonutOutputCache(CacheProfile = "TenMins")]
public ActionResult Index()
{
    return View();
}

If you are using cache profiles, be sure to configure the profiles in the web.config. Add the following within the system.web element:

<caching>
  <outputCacheSettings>
    <outputCacheProfiles>
      <add name="TenMins" duration="400" varyByParam="*" />
    </outputCacheProfiles>
  </outputCacheSettings>
</caching>

You can also configure the output cache to use a custom provider:

<caching>
  <outputCache defaultProvider="DistributedCacheProvider">
    <providers>
      <add name="DistributedCacheProvider" type="DevTrends.Example.DistributedCacheProvider" />
    </providers>
  </outputCache>
</caching>

Note, that a custom provider is not detailed here but you can write one fairly easily by subclassing System.Web.Caching.OutputCacheProvider. A number of implementations are also available on the web.

Hope this helps.

18 Dec 2015

Self referencing loop detected for property 'xxxx' with type 'System.Data.Entity.DynamicProxies.XXX_XXX'. Newtonsoft.Json.JsonSerializationException

This is a very common serialization exception we see when forget to use loop handling strategies in Web API.

13 Dec 2015

My session on Azure Media Services in C# Corner Delhi Chapter

After I moved to Delhi, first time I got an opportunity to speak with developers in C# Corner Delhi Chapter meeting, Dinesh Beniwal is awesome guy managing community so well in Delhi. He invited me to be a part of Delhi Chapter and engage with developers and help community to grow by sharing and learning.

2 Dec 2015

Sorting in WebAPI - a generic way to apply sorting

In this post you will learn how to implement sorting functionality in WebAPI so that client can ask for sorted data by sending columns names through query string. Client can send more than one short parameters and request for ascending or descending data in response. Sorting functionality should be generic enough so that we can reuse it.

1 Dec 2015

Field level data selection in WebAPI

In this post you will learn how to implement field level data selection functionality in WebAPI so that client can ask for less data by sending individual columns names through query strings variable fields.

29 Nov 2015

Upload video on YouTube in ASP.NET or MVC

In this post you will learn how to upload video on YouTube from your application. I’ve used ASP.NET Web Forms as well as MVC bits to implement all functionality easily. You can achieve similar functionality ASP.NET Web Forms or MVC alone.

26 Nov 2015

Write on Existing Image

In this blog post you will learn all about writing text or image on existing image. I will be developing this in ASP.NET Web Forms, but you can achieve this functionality in MVC or windows forms as well. I’ve posted another blog post which generates QR Code. Actually all this was part of my recent requirement which I would like share with you.

25 Nov 2015

QR Code Generation and Verification

In this blog post you will learn all about QR Code, starting from requirement to generation to verification. I am going to develop this in C# and in ASP.NET Web Forms, but you can use it with MVC, Desktop Apps etc. I will be using MessagingToolkit.QRCode open source library for everything here.

20 Nov 2015

Search in selected file types Visual Studio

This is a very important feature which is worth useful when making necessary changes that may match in multiples file types but you are only supposed to change in selective files types.

18 Oct 2015

Visual Studio 2015 Razor Syntax Highlighting and Intellisense not working

Today i faced this issue in my IDE and resolved with following steps:

14 Sep 2015

Roslyn csc.exe and vbc.exe deployment on shared hosting

Roslyn compilation is now default with .NET 4.5 means if you create any web application either Web Forms or MVC using .NET 4.5 you get this compilations bits pre-installed in your project.

Why use Roslyn compilation?

In nutshell, this enables many features which is very useful when developing application as well as when application is deployed on server.

24 Jul 2015

Language and Culture/UI Culture or Internationalization in MVC

Setting up Language and UI Culture in efficient way is very important. Also, there are many ways to achieve this today but the best way is always easy to achieve, clean, documented. I can see many posts online about this but they not much useful and end to end discussed, you end up with huge code.

18 Jul 2015

Stop Debugging stops IIS Express hence application stop running in browser in Visual Studio 2015

Note: This was a bug with Visual Studio 2015 Update 2 which is officially mentioned and fixed in Update 3. Read more here.

This is not a bug but as a web developer I personally expect when debugging stops browser should keep running through IIS Express instance. Next time, I make change in Visual Studio code then do a build and refresh browser, I’m addicted this way.

16 Jul 2015

The 'System.Web.Security.SqlMembershipProvider' requires a database schema compatible with schema version '1'

Error: The 'System.Web.Security.SqlMembershipProvider' requires a database schema compatible with schema version '1'

I received above error on my production machine after deploying new database for a web application. I have SQL Server 2008 R2 installed and to deploy database I created query file (.sql) schema with data. After that I deployed web application properly.

31 May 2015

MVC client side validation not working with modal or Bootstrap model

Recently in my one of the MVC Project, dynamically loaded content on Bootstrap modal client side validation was not working. By any chance if you face same issue this post is important for you.

An error occurred when trying to create a controller of type 'AlbumsController'. Make sure that the controller has a parameterless public constructor.

By any chance if you see below error, please use below resolving instruction to overcome.

An error occurred when trying to create a controller of type 'AlbumsController'. Make sure that the controller has a parameterless public constructor.

17 May 2015

LINQ to Entities does not recognize the method 'Int32 ToInt32(System.String)' method, and this method cannot be translated into a store expression

LINQ to Entities does not recognize the method 'Int32 ToInt32(System.String)' method, and this method cannot be translated into a store expression

First of all look at the screenshot of the error page

10 May 2015

Export table data into excel file

Exporting table data (DOM data) on the HTML page to excel file is a very common requirement. The simplest approach or say the completely client side approach to achieve this is to export the DOM data using client side scripts.