Facebook Logout Button In MVC Application

by Naveen 11. May 2012 08:43

Download Sample Project

In previous post, Use Facebook login in MVC, i discussed how you can use Facebook to authenticate users in your web application. Authentication implementation will not be complete without providing the user a way to logout out of the application. In this post I will show how to implement Facebook logout button in your MVC application.

Facebook Logout Button or Link

If you have not tried our application running on MVC4 (Developed with VS11), try Facebook login here Universal Shopping Mall. Once you will login, you will see logout button appear in top right side of the page as shown in image below.

Facebook Logout Controller and Action

Here is documentation from Facebook developer site about programmatically logging user out of Facebook.

You can programmatically log the user our of Facebook by redirecting the user to
https://www.facebook.com/logout.php?
    next=YOUR_REDIRECT_URL
   &access_token=USER_ACCESS_TOKEN
The URL supplied in the next parameter must be a URL with the same base domain as your application as defined in your app's settings.

This means when we send request to Facebook to log out user, it is going to call back on URL specified in next parameter. You will need to implement a controller to receive this call back from Facebook. Following snippet shows how I have set up a link for logout.

@Html.ActionLink("Logout", "Logout", "Account")
    

This means I have implemented an action Logout in my Account controller. This is same controller where I added Login action to perform login. Following code snippet shows implementation of this Logout action in demo application.

public ActionResult Logout()
{
  var fbUser = Session["fbUser"] as Models.FacebookUser;
  if (null == fbUser)
  {
   return new RedirectResult(Request.UrlReferrer.AbsoluteUri);
  }

  var redirectUrl = string.Format("https://www.facebook.com/logout.php?
        next={0}&access_token={1}",
         Request.UrlReferrer.AbsoluteUri, 
         fbUser.AccessToken);
  //TODO: Do book keeping about this Facebook user's activity.
  FormsAuthentication.SignOut();
  Session["fbUser"] = null;
  return new RedirectResult(redirectUrl);
}
    

You will notice that I have done following things before sending logout request to Facebook for this user.

  • Called FormsAuthentication.SignOut to remove authentication cookie for this user from the application.
  • Invalidated session variable containing this user's information. You can also call Session.Abandon at this stage to clear all session variables.

Once request returns from Facebook, the login button appears instead of logout button.

Demo and Sample Project

I have attached sample project with this post. You will need to replace your Facebook application information in web.config file. And you can see this all in action in real production application as Universal Shopping Mall.

 

Views: 179

Tags: , ,

ASP.Net

Facebook login in MVC Application

by Naveen 10. May 2012 15:52

Download Sample Project

As Facebook IPO is coming up soon, I decided to stir some activity around this blockbuster event. In this post I will be discuss how to authenticate users using Facebook OAuth in your MVC application. Following screen shot shows popular Facebook login button you may have seen at number of web sites and applications. Yes, I am going to discuss this very button and how you will implement authentication using Facebook.

Register your application in Facebook

Before you can begin using using Facebook for authenticating users on your web site, you will need to register your web site as a Facebook application on Facebook developer site. Here are the steps involved in registering your app.

  • Goto Facebook developer site and login with your account.

  • You will see Apps tab at top, click on it.

  • On next screen click on Create New App button on top right side as shown in screen shot below.

    Facebook will walk you through few steps in setting up your application. After you finish the steps, you will have the following information about your application.

    There are 3 very important pieces of information on this screen that you will need to work with OAuth authentication with Facebook.

    • App ID/App Key
    • App Secret
    • Site URL

    You can read more about their importance on Facebook site.

Display Facebook login button or link

First step is that we want to display login button our pages. I have set it up on my shared layout in demo application. Following snippet shows how I have set it up.

@{
 var fbLoginUrl = Url.RouteUrl(new { Controller = "Account", Action = "Login" });
}
@{
  if (Request.IsAuthenticated)
  {
     var fbUser = Session["fbuser"] as MvcFaceBook.Models.FacebookUser;
     <span>Welcome @fbUser.UserName</span>
  }
  else{
    <a href="@fbLoginUrl"><img src="/content/images/facebooklogin.png" /></a>
  }
}
    

Set up contoller for facebook login button

You can notice from code snippet above that I have set up RouteUrl to create a link that is using Account controller with action as Login. Following code snippet shows how this controller implementation looks like.

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

  public ActionResult Login()
  {
    // Create a token in session to save state of this request. We will use
    // this to verify oAuth response from Facebook.
    var requestState = new Helpers.FacebookRequestState()
    {
      Id = Guid.NewGuid().ToString("N"),
      Url = Request.UrlReferrer.ToString(),
      CreationTime = DateTime.Now
    };
    Session[requestState.Id] = requestState;
    var redirectUrl = string.Format("http://www.facebook.com/dialog/oauth/?
        client_id={0}&
        redirect_uri={1}facebook/OAuth/&
        state={2}",
        ConfigurationManager.AppSettings["fb-applicationid"],
        ConfigurationManager.AppSettings["fb-connecturl"],
        requestState.Id);
     var redirResult = new RedirectResult(redirectUrl);
     return redirResult;
    }
}
    

As you can see that Login action does not return any view in the application itself. It is redirecting the login request to facebook's OAuth authentication dialog box. This is where three pieces of information about your Facebook application get used. That information is passed along with request URL to Facebook for verification of your request. I have stored that information in my application in web.config file and then reading from it.

Set up MVC controller to receive response from Facebook authentication

Once user has logged into Facebook and accepted use of your application, Facebook will send a response to URL that you have sent in redirect_uri query string parameter. This URL has to be based on Site URL value that you have used when registering your application. For example I have used Site URL as localhost/MvcFaceBook for my application. And I have set redirect_uri in OAuth request to be localhost/mvcfacebook/facebook/OAuth. Facebook will send response to this Url. That means my application is going to need a route that can handle this request. Based on my setting, I have created FaceBookController with a action OAuth in it. Now my MVC application is all set to receive the response from Facebook. Following code snippet shows how my controller looks like.

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

  [HttpGet]
  public ActionResult OAuth(string code, string state)
  {
    if (string.IsNullOrEmpty(code))
    { return View(); }
    if (string.IsNullOrEmpty(state))
    { return View(); }

    var requestState = Session[state] as Helpers.FacebookRequestState;
    var fbHelper = new Helpers.FaceBookHelper();
    var accessToken = fbHelper.GetFbToken(code);
    var fbUser = fbHelper.GetUser(accessToken);
    Session["fbuser"] = fbUser;
    FormsAuthentication.SetAuthCookie(fbUser.UserName, false);
    return new RedirectResult(requestState.Url);
    }
}
    

Notice the signature of Action method. It takes two parameters, "code" and "state". Facebook authentication service returns the handshake code in this "code" parameter. This is the code that you return back to Facebook to get access token. Second parameter "state" corresponds to "state" query string parameter that you can pass with authentication request. Facebook will return that parameter as it is in response query string. You can use that parameter for some book keeping purposes. For example I am using that parameter to verify if the response from Facebook corresponds to one of the requests from the site and I am saving additional information in session about that request. For example I have saved the Url of page from where login request started. When login is complete, I am redirecting user back to same page. You can utilize this parameter as per need of your application.

Getting Facebook user information using FaceBook SDK

Once you have successfully obtained access token from Facebook, you can use that to request rest of the user's data from Facebook. For example I have used Facebook C# SDK to get user's id, name and username using access token. Following code snipper shows use of Facebook SDK.

public Models.FacebookUser GetUser(Helpers.FacebookAuthToken accessToken)
{
  var fbClient = new FacebookClient(accessToken.Token);
  dynamic me = fbClient.Get("me", new {fields = "id,name,username"});
  Models.FacebookUser fbUser = null;
  if (null != me)
  {
   fbUser = new Models.FacebookUser()
   {
    Id = Convert.ToInt64(me.id),
    Name = me.name,
    UserName = me.username
   };
  }
  return fbUser;
}
    

Demo and Sample Project

You can see use of Facebook login in MVC application at my playground site Universal Shopping Mall. You will see Facebook login at top right corner. I have attached a demo project with this post that implements all the functionality. You will have to replace the information about your Facebook application in app settings section of web.config file.

 

Views: 192

Tags: , ,

ASP.Net

MVC Ajax Request Error handling

by Naveen 7. May 2012 15:53

Download Sample Project

In previous post, how to use ajax in mvc application, I talked some basic concepts of using ajax in mvc application. The big assumption in that discussion was that everything works smoothly, there are not errors in execution and ajax returns response that we expected. In reality things do not always work as planned. We have to account for unexpected conditions, errors and other unhandled exceptions etc. In this post I will discuss following concepts related to MVC web applications.

  • Implementing custom AuthorizeFilter to extend authorization
  • Handling failed ajax request on client side to display error message

Authorize Ajax request using AuthorizeAttribute

AuthorizeAttribute does not have any direct relation to discussion on handling of errors in ajax requests. But I took the oppurunity to demonstrate how you can implement custom filters on your controllers. Authentication and authorization are the building blocks of secure application. It is important that you have authorize the requests coming in to your MVC application appropriately to prevent execution of unauthorized code.

If only requirement for your application is that caller needs to be authenticated, then you can use AuthorizeAttribute directly and there is no need for any custom implementation. But if there is more that needs to be done and can not be handled by AuthorizeAttribute class then you will need to implement new class that derives from AuthorizeAttribute. The following code snippet shows class that I implemented for demo project.

public class AsyncAuthorizeAttribute : AuthorizeAttribute
{
  protected override bool AuthorizeCore(HttpContextBase httpContext)
  {
     // TODO: Perform authorization check here. If the call is not
     //       authorized, then return false. Otherwise return true
     //       from this method.
    return base.AuthorizeCore(httpContext);
  }

  protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
  {
    if (filterContext.HttpContext.Request.IsAjaxRequest())
    {
      var urlHelper = new UrlHelper(filterContext.RequestContext);
      filterContext.Result = new ViewResult()
      {
        ViewName = "UnauthorizedAccess"
      };
    }
    else
    {
      base.HandleUnauthorizedRequest(filterContext);
    }
  }
}
    

There are two important methods that can you can override to control how authorization checks happen for method or class on which you put this attribute.

  • AuthorizeCore: This method is called to get a vote on if request is authorized or not. The base implementation will always return false if user has not logged in. This is the place where you can perform additional check. The method is passed the whole context of this request in HttpContextBase parameter. If you return false from this method, your request will send 401 status code back to caller.
  • HandleUnauthorizedRequest: If you are not looking into doing anything special if request is unauthorized then you do not have to override this method. You can see from my implementation, I am trying to handle unauthorized request for Ajax differently. This implementation is blocking send of 401 error code in response and instead sending a view that has some informaiton about the failure. Now you may be asking why not just let 401 status code goto client. I will discuss this in more detail now.

Handling Unauthorized Ajax Request

If you send 401 status code in response to Ajax request, you will end up a view something looking like below.

You can see that place where Ajax response was supposed to insert HTML for successful request, you have your login page displayed there. The reason is that when authorization failed, ASP.Net framework redirected the request to login page that was set in web.config file. This is not what you intended. You wanted to show message to the user that he or she needs to login if they want to execute the action on the page. This is why I have custom implementation in HandleUnauthorizedRequest method for Ajax request. I have created a partial view in project that contains the HTML that will be shown to user when authorization fails. Following snippet shows that partial view.

@{
    Layout = null;
}
<p>You will need to log in to this site to execute this operation! 
        Please click on the following link to proceed.</p>
<p>
    @Html.ActionLink("Login", "Login", "Account")
</p>
    

Now when this authorization fails, Ajax famework the following HTML into element specified by UpdateTargetId property value in AjaxOptions class when you set up the request.

UpdateTargetId and OnFailure

There is one little fine print that is missing in MVC documentation. HTML element indicated by UpdateTargetId id is only updated when Ajax request succeeds. When request fails, the framework will not insert any error message in that HTML element. So if you want to display some message to user or you want to know more about the error, then you will have to implement a client side function for OnFailure event handler. In that client side javascript code, you can extract error information from first parameter passed to the function. Following code snippet shows how I managed to display some details about the exception thrown from server in response to my Ajax request.

function onMessageSendFail(request, status) {
    var errorDiv = $('#errorresponse');
    errorDiv.html(request.responseText);
}
    

The detailed error message looked like below when i forced an exception from code.

Server Error in '/' Application.
--------------------------------------------------------------------------------
 Operation is not valid due to the current state of the object. 
Description: An unhandled exception occurred during the execution of the current web request. 
Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.InvalidOperationException: Operation is not valid due to 
the current state of the object.

Source Error: 
Line 22:         public ActionResult Index(Models.ContactUsViewModel contactUs)
Line 23:         {
Line 24:             throw new InvalidOperationException();
Line 25:             return View("ContactUsResponse", 200);
Line 26:         } 

Stack Trace: 
    

Sample project attached with this post contains all the code that demonstrates all the concepts that I discussed above.

 

Views: 178

Tags: ,

ASP.Net

How to use Ajax in MVC applications

by Naveen 6. May 2012 16:04

Download Sample Application

In this post, I will discuss some basic building blocks of using Ajax or Async mechanism in MVC applications. I will not go into details about what is Ajax or what is Async mechanism. There are lot of good and informative books and posts about the topic.

MVC framework helps in providing mechanism of implementing Ajax features in your web applications. When you create a new web application, you will notice following lines in web.config file.

<appSettings>
  <add key="ClientValidationEnabled" value="true" />
  <add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
    

Notice setting of UnobtrusiveJavaScriptEnabled app setting value. This indicates to MVC framework that your application needs to include JS support for implementing Ajax or Async mechanims. Microsoft uses jQuery based implementation to accomplish this task.

For this discussion I have implemented a Contact Us page in web application. This page takes 3 input values from a user and then submits that information to server using Ajax. The following screenshot shows how this page looks like in my application.

Setting up model for the page

First set up model representing the information on the page for which you want to implement Ajax. For my application, I have created a very simple model object that contains these 3 pieces of the information.

public class ContactUsViewModel
{
  public string Name { get; set; }
  public string Email { get; set; }
  public string Message { get; set; }
}
    

Create Controller for page and ajax request

This is the important part of the implementation. We will need to set up controller and action that will be executed when client sends ajax request to server. And then server send appropriate response for client to render. I have created a ContactUsController for my page that serves default view for GET request and serves a different view after getting ajax request from client. Following snippet shows my simple set up. In your real application there will be more implementation when server receives data. This prototype shows how this all will be set up.

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

  [HttpPost]
  public ActionResult Index(Models.ContactUsViewModel contactUs)
  {
   return View("ContactUsResponse", 200);
  }
}
    

Setting up Html form for Ajax in Mvc

Next step is to create views that we are going to server when user loads the page and then sends message.

@model MvcAsyncForms.Models.ContactUsViewModel
@{
    ViewBag.Title = "Contact Us";
    AjaxOptions ajaxOptions = new AjaxOptions()
    {
        UpdateTargetId = "messageresponse",
        Url = Url.Action("Index"),
        LoadingElementId = "sendingmessage",
        LoadingElementDuration = 3000,
        OnComplete = "onMessageSent"
    };
}
<div id="sendingmessage">
    <p>Sending your message .....</p>
</div>
<div id="messageresponse"></div>
<div id="contactUsForm">
    <h2>Contact Us</h2>
    @using (Ajax.BeginForm(ajaxOptions))
    {
        <table>
            <tr>
                <td><span>Name:</span></td>
                <td>@Html.EditorFor(m => Model.Name)</td>
            </tr>
            <tr>
                <td><span>Email:</span></td>
                <td>@Html.EditorFor(m => Model.Email)</td>
            </tr>
            <tr>
                <td colspan="2"><span>Message:</span></td>
            </tr>
            <tr>
                <td colspan="2">
                    @Html.TextAreaFor(m => Model.Message)
                </td>
            </tr>
            <tr>
                <td colspan="2">
                    <div style="text-align: center">
                    <input type="submit" value="Send Message" />
                    </div>
                </td>
            </tr>
        </table>
    }
</div>
<script type="text/ecmascript">
    function onMessageSent() {
        $('#contactUsForm').hide();
    }
</script>
    

There are two pieces in this view implementation. First you will need to set up AjaxOptions object that specifies all the ajax related options. You can see that we have set up following properties to indicate how we want to execute ajax request and how response will be rendered.

  • Url: This property sets up the POST url where requests will be sent
  • UpdateTargetId: This is HTML element that will be updated with response sent by server after processing ajax request
  • LoadingElementId: This is the HTML element that will be shown to user while ajax request is being executed and user is waiting for request to complete. This where you can show some message or some animation to indicate to the user that execution is in progress. This is a good practice that you should keep the users aware of progress of their request.
  • OnComplete: This is client side event triggers that when ajax request is completed. There are four events that are triggered for ajax request, OnBegin, OnComplete, OnSuccess and OnFailure. These allow you to handle various stages of ajax request so you can take action on client side accordingly. For demo purposes I have only handled OnComplete event where I am hiding request form after ajax request is complete.

There are more options that you can set in AjaxOptions class. I will discuss more advanced settings in subsequent posts. For this discussion I have only set most basic ones to get the job done.

Ajax.BeginForm

This is the place where you set up HTML form that will be used to send the data to server to execute your ajax request. There are about 12 overloads available for this method. I have used the most basic one that takes AjaxOptions as parameter to set up the request. In this block you will set up all the client side form that contains the data to be submitted to server.

Response for Ajax request

MVC framework makes it very easy for us to send us well formatted HTML response for any ajax request. And then it uses element represented by UpdateTargetId in AjaxOptions to display the response on client side. I have implemented a partial view that is sent back to client when ajax request is complete.

@model int
@{
    Layout = null;
}
@if (Model == 200)
{
    <span style="color: #00ff21; font-size: 1.2em;">Your message has been sent!</span>
}
else
{
    <span style="color: #f00;font-size: 1.2em">Your message could not be sent!</span>
}
<p>
@Html.ActionLink("Home", "Index", "ContactUs")
</p>
    

You can see how easy it is to implement Ajax in MVC web applications. In subsequent posts I will discuss more advanced details about the use of Ajax in MVC applcations.

Demo and sample code

You can see this in action at UniversalShoppingMall site that has been created using MVC4 with VS11. You can click on Contact Us link in top navigation and see how the ajax request works. The demo project included in this post is a simple stand alone implementation of this contact page.

 

Views: 215

Tags: ,

ASP.Net

Custom paging with search term in MVC4 application using VS11

by Naveen 4. May 2012 16:00

searching, displaying lists of results and paging through them is one of the most common tasks we perform in web applications. In ASP.Net when you use controls like GridView, ListView etc. along with viewstate, things are little straight forward. But when you use are using stateless mechanism with MVC framework, then things are little different.

In this post I will show I implemented paging in MVC4 application and preserved search query in routing urls so that when a user is clicking on pager, the search query gets passed along. For demo purposes I have built a shopping mall using Amazon's product advertising web service as product store.

I will start with showing the razor syntax for pager on my page.

<div class="pager">
 @Html.PageLinks(Model.PagingInfo, Model.QueryParameters.Keywords, 
    x => Url.Action("List", 
    new {page=x, category=Model.Category.Name, keyword=Model.QueryParameters.Keywords}))
</div>
    

I have implemented an extension method PageLinks that is used to generate HTML for pager. The key part of this implementation is the last parameter to this method where I am passing product category name along with the search query string. Lets see how the method signature looks like.

public static MvcHtmlString PageLinks(this HtmlHelper html, 
    PagingInfo pagingInfo, string query, Func<int, string> pageUrl)
{...}
    

This methos is responsible for returning HTML string. Now let me some code from this function that builds these paging links.

for (int i = start; i <= end; i++)
 {
   tag = new TagBuilder("a");
   tag.MergeAttribute("href", pageUrl(i));
   tag.InnerHtml = i.ToString();
   if (i == pagingInfo.CurrentPage)
   {
    tag.AddCssClass("selected");
   }
   pagingLinks.Append(tag.ToString());
 }
    

The following image shows the pager looks like on the web site.

custom paging with search string in mvc

Generated HTML for pager

<div class="pager">
    <span>Page:</span><a class="selected" href="/Electronics?keyword=iphone">1</a>
    <a href="/Electronics/Page2?keyword=iphone">2</a>
    <a href="/Electronics/Page3?keyword=iphone">3</a>
    ......
</div>
    

You can see that the pager URL contains the information about page number and search string is contained in the query string. Now lets see how the route looks like along with controller signature that routes the click on these links correctly.

routes.MapRoute(
   null, "", new { Controller = "Product", action = "List", 
                   category = (string)null, keyword = (string)null, 
                   page = 1 });

routes.MapRoute(
   null, "Page{page}", new { Controller = "Product", action = "List", 
                             category = (string)null, keyword = (string)null },
                             new { page = @"\d+" });

[AcceptVerbs(HttpVerbs.Get)]
public ViewResult List(string category, string keyword, int page = 1)
{....}
    

It is very important that you set up your routes correctly when you are implementing paging with more information than just page index and search query terms.

Demo Application

You can see all this in action at UniversalShoppingmall. You can play around by putting some search term in text box and playing with paging control to see how the URL in pager changes and how the URL looks like in browser.

 

Views: 215

Tags: ,

ASP.Net

How to pass arguments to constructor with Ninject dependency injector

by Naveen 28. April 2012 07:53

When using dependency injection, some time we need to pass additional parameters in constructor of that object. Ninject provides a very handy method that you can use to pass arguments when you bind the interfaces. I have a similar situation in my shopping web site. I uses MVC framework. It has an interface for repository component of the web site. One of the repository used in the application is Amazon web service. Each amazon web service needs to be associated with some identity parameters. The class that implements repository for amazon web service requires that caller passes identity parameters. You could argue that why this parameter is not a dependency as well so I could use binding for it. The problem is that it is hard to come up with a unified identity interface for each type of b2b web services. Therefore it made sense that each repository will handle this identity parameters on its own.

The following code shows how WithConstructorArgument method is used to pass parameters to constructor when Ninject creates instance of the object.

private void AddBindings()
{
   RequestIdentity identity = new RequestIdentity()
   {
      AssociateTag = ConfigurationManager.AppSettings["awsassociatetag"],
      AccessKey = ConfigurationManager.AppSettings["awsaccesskey"],
      SecretKey = ConfigurationManager.AppSettings["awssecretkey"]
   };
   NinjectKernel.Bind<IProductsRepository>().
    To<ProductsRepository>().
    WithConstructorArgument("identity", identity);
 }

Following code shows ProductRepository class implementation that is expecting the parameter to be passed to it.

public class ProductsRepository : IProductsRepository
{
     private RequestIdentity Identity { get; set; }
     public ProductsRepository(RequestIdentity identity)
     {
        if (null == identity)
        {
            throw new ArgumentNullException("identity");
        }
        Identity = identity;
     }
}
 

Views: 254

Tags: , ,

.Net | ASP.Net

Mvc - How to pass parameters in Html.BeginForm action url

by Naveen 26. April 2012 06:15

In my previous post Authentication and Dynamic content in MVC using Model Binding I described how you can bind your model to input controls and then binding will transport the values back and forth between client and server. In this post I will extend this concept and show how to pass some additional parameters with FORM's post action along with the data that will be passed with model binding.

One of the common activities in an application is to perform search. For that we get input from user in text box ,some drop down or some other form of control. Then that information is passed back to server to perform search on some repository and return results to the user. In the sample project, I am trying to add a search box on my product listing page.

mvc search box

Model Binding With Text Box

To take advantage of model binding, I have bound my view to a ViewModel class in my application. One of the objects in this view model is QueryParameters which contains a property named Keywords. So in my FORM rendering, I have bound the text box to this property. Based on this approach the code looks like as below.

Razor View Code
@model ByteBlocks.ShoppingMall.Models.ProductListViewModel
@{
    ViewBag.Title = "Products";
}

    
Controller Code
[HttpPost]
public ViewResult Search(ProductListViewModel model)
{
   return View();
}
    

This works like a champ. If I was not interested in filtering the search based on any other existing criteria, this will fly. But if you look at the image above, you will notice that on left side there is a navigation bar that has product categories. So if a user is interested in searching for some item in certain category, then I will have to let my Search action know about that as well. This means FORM's post action will need to carry more data. There are few approaches you could take.

  • We can take advantage of model binding by adding a new property, Category, to QueryParameter and then add a hidden field to form which will bind to this property.
  • Second approach would be to take advantage of Html.BeginForm method's overload and pass additional parameters to FORM's post data. Since I already have route that knows about product category, I can get the value of this route parameter using ViewContext and pass it back and forth. I like this approach because now I don't have to extend my view model object for something that may or may not be required. In this particular case product category was going to be part of the view model so it was perfect to take advantage of model binding. But there will be cases where you could take advantage of FORM's post data package itself and pass the data to server.

Based on the second approach the code changes as below.

Razor View Code
@using (Html.BeginForm("Search", "Product", new { category = ViewContext.RouteData.Values["category"] })) { @Html.EditorFor(m => m.QueryParameters.Keywords); <input type="submit" value="Search" /> }
Rendered Html
<div id="Div2">
<form action="/Product/Search?category=Apparel" method="post">
 <input class="text-box single-line" type="text" value="" />        
 <input type="submit" value="Search" />
</form></div>
    
Controller Code
[HttpPost]
public ViewResult Search(string category, ProductListViewModel model)
{
  return View();
}
    

Notice how rendered HTML has appended category as query string parameter to form's action URL. And Mvc framework passes that as parameter with same name in controller's action method.

View content of ViewContext

You can view content of ViewContext object in your page at any time by setting a break point in Razor view itself. Then in debugger's immediate window you can type ViewContext and go from there. Following snippet shows how I looked at contents of ViewContext object in my application.

ViewContext.RouteData.Values.Keys
Count = 4
    [0]: "Controller"
    [1]: "action"
    [2]: "category"
    [3]: "page"
ViewContext.RouteData.Values["category"]
"Apparel"
    

In subsequent posts I will discuss some more tips and tricks related to Mvc4 using VS11.

 

Views: 358

Tags: ,

Compiler Error Message: CS1061 - MVC4 using VS11

by Naveen 25. April 2012 15:34

While working on my MVC4 web application using VS11, I ran into the following error. I have an extension method that was to be called from razor page.

Compiler Error Message: CS1061: 'System.Web.Mvc.HtmlHelper<ByteBlocks.ShoppingMall.Models.ProductListViewModel>' does not contain a definition for 'PageLinks' and no extension method 'PageLinks' accepting a first argument of type 'System.Web.Mvc.HtmlHelper<ByteBlocks.ShoppingMall.Models.ProductListViewModel>' could be found (are you missing a using directive or an assembly reference?)

The error itself is self explanatory that application is not able to locate the extension method. This means that the namespace that contained the extension method needs to be included on the page. There are two ways you can accomplish this. First is by adding the namespace in web.config file in page > namesapces section as shown below. This web.config file is the one that you have under Views folder, not the one in root folder of application.

<system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, 
    System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="ByteBlocks.ShoppingMall.Helpers" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>

Second way to include namespace is by adding @using directive at the top of your razor page as shown below.

@using ByteBlocks.ShoppingMall.Helpers
 

Views: 287

Tags: ,

ASP.Net

How to use Ninject to insert dependency using constructor pattern

by Naveen 22. April 2012 15:01

Download Sample Application

Recently I was working on a prototype for implementation of logging mechanism for my application. Previously I used to use Unity for Dependency Injection (DI) to inject different logging frameworks into the application for integration and unit testing. Now I am switching to using Ninject for DI. In this post I will how you can to use Ninject in your applications. I will not go into details why I chose Ninject and not Unity for future projects. That will be topic for discussion for another day. For now I will summarize it in one line that Ninject is light weight and easy to use framework as compared to Unity.

Download Ninject Framework

You can download Ninject from Codeplex. Or better option is to get it using NuGet manager. Add reference to Ninject.dll in your project.

Create Interface and Classes for DI

For my logger, I created interface IAppLogger that will act as interface for all logging methods for my application. Following snippet shows sample of this interface.

public interface IAppLogger
{
  void Log(..............);
  void Log(..............);
}
    

Following code snippet shows sample of concrete class implementation for this interface. This class implements logging mechanism using Log4Net.

public class Log4NetLogger : IAppLogger
{
 private static readonly ILog MyLog = LogManager.GetLogger(typeof(Log4NetLogger));

 public Log4NetLogger()
 {
   BasicConfigurator.Configure();
 }
       
 public void Log(string id, string context, string methodName, 
                 string methodParams, string value)
 {
    MyLog.Info("Start");
    MyLog.Error(string.Format("{0} {1} {2} {3} {4}", 
        id, context, methodName, methodParams, value));
    MyLog.Info("End");
 }

 public void Log(string id, string context, string methodName, Exception ex)
 {
   MyLog.Info("Start");
   MyLog.Fatal(context, ex);
   MyLog.Info("End");
 }
}
    

Now that we have interface and class set up to include in DI, we can now look at how Ninject makes it easy to implement DI.

Implement Ninject Module

First step in using Ninject is to bind interface to object that will need to be created when application encounters DI. Create a class that derives from NinjectModule. Override Load method to include bindings. In this sample I will just use a simple implementation of Bind method. There are more advanced overloaded methods available to control the binding in more controlled way. For this sample, the following simple implementation will work.

public class LoggerModule : NinjectModule
{
  public override void Load()
  {
    Bind<IAppLogger>().To<Log4NetLogger>().InSingletonScope();
  }
}
    

What this code means is that every time there is an instance of IAppLogger to be injected into the application, create an instance of Log4NetLogger class. Since we need singleton instance for logger, we call InSingletonScope method that indicates to Ninject to create singleton Log4NetLogger class.

You can include all bindings of your application in one module. But it is preferred that you create multiple modules and include binding related to certain sections of the application into appropriate modules.

Add NinjectModules into framework

Now that we have implemented our NinjectModule we need a way to tell Ninject framework about this. You can add one more modules into IKernel object of Ninject. Following method show how DI framework gets to know about our modules.

static void SetupDI()
{
  NinjectKernel = new StandardKernel(new LoggerModule());
}
    

Add DI to class using Inject attribute

Now we have DI framework set up for our logger interface. Lets see how we are going to use DI in our classes. In this sample, I have create AmazonRepositary class. I would like to inject IAppLogger object into this class so I can log any errors or information into my logger. Following code snippet shows how I used Inject attribute to insert IAppLogger to class. In this case I am using Constructor Injection pattern.

public class AmazonRepository
{
   private IAppLogger _appLogger;
        
   [Inject]
   public AmazonRepository(IAppLogger appLogger)
   {
     _appLogger = appLogger;
   }

   public void GetProducts(SearchParameters searchParams, string ip)
   {
        .....
   }
}
    

Inject attribute lets Ninject framework know that when Ninject kernel is used to create an instance of AmazonRepository object, it will create an instance of IAppLogger object and inject that into class constructor. Following code shows how kernel object is used to create this class.

var repo = NinjectKernel.Get<AmazonRepository>();
    

You can see that your implementation does not need to know what logger class is going to be used when creating instance of injected interface. You have already set up the binding in NinjectModule. By writing few lines of code we have managed to use Ninject as our DI framework. In subsequent posts, I will discuss other DI patterns and some advanced use of binding mechanisms.

Sample Code

I have attached sample project with this post that I used for demonstrate use of constructor patterns for DI. This project was created using VS11 and .Net 4.5. There is nothing specific to .Net4.5 used in this implementation. You should just be able to use the same code in VS2010.

 

Views: 238

Tags: ,

.Net

Windows 8 - Recycle Bin

by Naveen 21. April 2012 17:29

In this post I will discuss where you will find Recycle Bin in Windows 8 and to take action on items in recycle bin. The topic seems kind of simple, but when you start using Windows 8 and Metro UI, there are some old features that will never get old and cleaning up disk on your machine is one of the ones.

When you start Windows 8, you have Metro UI up and running. To access Recycle Bin you will need to switch to Desktop. There are two ways you can do it. You can use Desktop title from Metro UI or you can hit Start/Windows button on your keyboard. This will bring you to classic desktop ui mode. Here you will see familiar Recycle Bin icon at top left location. Double click on it and bring up your dialog box for recycle bin.

windows 8 recycle bin

You will notice that the top menu part of this dialog box looks little different than what you are used to seeing prior to Windows 8. You may wonder what happened to buttons like Restore or Empty Recycle Bin. They are still there but you need one more click now. Notice there is Recycle Bin Tools button. And under that there is Manage button. Clicking on it will bring up ribbon that has the buttons that you were looking for.

windows 8 recycle bin
 

Views: 179

Tags:

Smart Phones Poll

What smart phone do you currently own?





Show Results

Month List

Powered by BlogEngine.NET 2.0.0.49
Theme by Naveen Kohli