Udemy

asp.net mvc Adding Custom direcotry for Views (asp.net mvc How to specify which folder the View pages reside in?)

Sunday, October 26, 2014 0 Comments A+ a-


Introduction :


In asp.net mvc by default when we create application, our Views reside in Views directory for our Controller actions. For Example, by default it create Home controller with Index action, and if we see in Solution Explorer in Views directory we can see directory Views -->> Home --> Index.cshtml  and we have its action like this:

 
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}

and we have this action's Views in Views folder see the following screen :




Now by default it will first look for Index.cshtml file in Views/Home folder and it is unable to find it there then it will find in View/Shared folder, if it also not finds it there it will throw exception that view file is not found, here is the exception text which is thrown:


The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Home/Index.aspx
~/Views/Home/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Views/Home/Index.cshtml
~/Views/Home/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml

 

See:


The same is the case for partial view when we call return PartialView() it first looks in the respective controller's Views/Home  directory in the case of HomeController and in case of failure it looks in the View/Shared folder.

Using Custom Directories:

Now what if i had make a separate directory for partial views in my Views folder and Shared folder like : 



Views/Home/Partials and Views/Shared/Partial then we have to tell the ViewEngine  to look in that directory as well by writing the following code in Gloabl.asax  file in  Application_Start event.

For Example i have this code and i am returning _LoginPartial.cshtml from Index action of HomeController , now what will happen it will look in View/Home directory first and in failure it will look in View/Shared , but this time i have my partial views in seperate directory named Partial for every controller and for shared as well, In this case HomeController partial views are in Views/Home/Partials  and in Views/Shared/Partials:


public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}

In this case also i will get the same exception as Engine will not be able to find the View file _LoginPartial.cshtml.

The beauty of asp.net mvc framework is the  extensiblity which you can do according to your needs and business requirements, one of them is that  if you want your own directories structure for organizing your views you can register those directories with razor view engine, doing that will make your life easy as you will not have to specify fully qualified path of the view, as razor will know that it needs to look for the view in those directories as well which you have registered with it. 

So what we have to do is to register this directory pattern in the application so that every time call any View it should look in those direcotries as well in which we have placed the View files. So here is the code for that

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        AuthConfig.RegisterAuth();

        RazorViewEngine razorEngine = ViewEngines.Engines.OfType<RazorViewEngine>().FirstOrDefault();
        if (razorEngine != null)
        {
            var newPartialViewFormats = new[] 
          { 
            "~/Views/{1}/Partials/{0}.cshtml",
            "~/Views/Shared/Partials/{0}.cshtml"
          };

            razorEngine.PartialViewLocationFormats = razorEngine.PartialViewLocationFormats.Union(newPartialViewFormats).ToArray();
        }
    }
}

Now whenever we will call return PartialView("SomeView") it will look in that Controller Views directory's subdirectiry named Partials as well and in case it not finds there it will look in both Views/Shared and Views/Shared/Partials.

Points of Interest:

We saw how we can include other directories as well to be looked when getting View.The same way you can register other directories or your own Custom directory structure if you need to, so doing this way you will not need to specify complete path for like return View("~/Views/Shared/Paritals/Index.cshtml") instead of that you can just write then return View() if you want to load Index View and your action name is also Index which is being called, or if you want some other view to be rendered or some other action is invoked and you want to return Index view then you can write now return View("Index")

Udemy

Application UI hangs on long running operation in C# WindowsForm and WPF (BackgroundWorker in C#)

Thursday, October 23, 2014 0 Comments A+ a-

Once i came across a scenario in a Windows Presentation Foundation where on click of a button i needed to call a Restful Service which returns JSON and then i needed to deserialize the JSON and do soemthing with that, but when i wrote the code in the button event, it worked successfully but one thing that i noted that unitl the all operation completes my button remains pressed and UI also not responsive , so after researching a little i came to know this:

When we have some long running code that can take much time than normal time we should execute in a background thread not on UI thread, becasue executing it in UI thread will make our application un responsive and user will get irritated, here is my code which was executing directly on UI thread in button event:



This worked fine but as it is executing all the code on UI thread the application becomes unresponsive and user has to wait for the process to complete which is not a good user experience in any software or web application, after a  little reasearch i came to know about BackgroundWorker class which executes the code in separate thread not in UI thread.

This is the first version in which it was all happening on the UI thread all was fine but my button state was in pressed state and UI blocked until the service call completed and GridView populated.


private void btnLookup_Clicked(object sender, RoutedEventArgs e)
{

    string url = "http://www.lyfechannel.com/channels/allscripts/allscripts_institutions.php?allscripts=XXXX&user=YYYY&password=ZZZZ";

    WebRequest request = WebRequest.Create(url);

    request.Timeout = 500000;

    WebResponse response = request.GetResponse();

    var reader = new StreamReader(response.GetResponseStream());

    string json = reader.ReadToEnd();

    var jsonAsCSharp = JsonConvert.DeserializeObject<JSONWrapper>(json);

    PatientGrid.DataSource = jsonAsCSharp.Patients;
}

Now i am showing the version in which i used BackgroundWorker class, First of all create BackgroudWorker instance assign its events:


private void MyMethodToCallExpansiveOperation()
{
    //Call method to show wait screen
    BackgroundWorker workertranaction = new BackgroundWorker();
    workertranaction.DoWork += new DoWorkEventHandler(workertranaction_DoWork);
    workertranaction.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
        workertranaction_RunWorkerCompleted);
    workertranaction.RunWorkerAsync();
}

Now write the expensive operation code in workertranaction_DoWork method:


private void workertranaction_DoWork(object sender, DoWorkEventArgs e)
{
    string url ="http://www.lyfechannel.com/channels/allscripts/allscripts_institutions.php?allscripts=XXXX&user=YYYY&password=ZZZZ";

    WebRequest request = WebRequest.Create(url);

    request.Timeout = 500000;

    WebResponse response = request.GetResponse();

    var reader = new StreamReader(response.GetResponseStream());

    string json = reader.ReadToEnd();

    var jsonAsCSharp = JsonConvert.DeserializeObject<JSONWrapper>(json);

    patients = jsonAsCSharp.Patients;
}


and in  workertranaction_RunWorkerCompleted  bind List of Patients with Grid, as Do_Work does not executes in UI thread so we cannot access them in this method:


private void workertranaction_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    PatientGrid.DataSource = patients;
}

Now on button click we need to just call MyMethodToCallExpansiveOperation method:


private void btnLookup_Clicked(object sender, RoutedEventArgs e)
{
    MyMethodToCallExpansiveOperation();
}
Udemy

difference between ~= and *= in jquery

Wednesday, October 15, 2014 0 Comments A+ a-

Few days back, i saw a SO question, that what is the difference between [attribute~=value] and [attribute*=value]?



*= is attributeContains selector , From jquery docs:
Selects elements that have the specified attribute with a value containing a given substring.
~= is attributeContainsWord selector , From jquery docs:
Selects elements that have the specified attribute with a value containing a given word, delimited by spaces.


The attributeContains selector is for the string to be contained in the attribute value while attributeContainsWord selector is for string seperated with delimeted space. The official jquery examples clearly explain it.



Attribute Contains Selector [name*="value"]

HTML:

<input name="man-news">
<input name="milkman">
<input name="letterman2">
<input name="newmilk">
JQUERY:

$( "input[name*='man']" ).val( "has man in it!" );
OUTPUT:


Here is the fiddle demonstrating the Attribute Contains Selector [name*="value"] behavior

Attribute Contains Word Selector [name~="value"]

HTML:

<input name="man-news">
<input name="milk man">
<input name="letterman2">
<input name="newmilk">
JQUERY:


$( "input[name~='man']" ).val( "mr. man is in it!" );

OUTPUT:

Here is example demonstrating the behavior of  Attribute Contains Word Selector [name~="value"]