Inject dependency into WebApiConfig class in ASP.NET Web Api using Ninject

by sunil ravulapalli /31. August 2013 01:46 /asp.net-web-api /Comments (0)


First you have to make the WebApiConfig into a non static class as shown below.
Notice, that the dependency I want to be inject is IAccountsService.

public class WebApiConfig
{
	private static IAccountsService _accountsService;
	public WebApiConfig(IAccountsService accountsService)
	{
		_accountsService = accountsService;
	}

	public void Register(HttpConfiguration config)
	{
		var authentication = CreateAuthenticationConfiguration();
		config.MessageHandlers.Add(new AuthenticationHandler(authentication));

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

		config.EnableSystemDiagnosticsTracing();
	}

	private AuthenticationConfiguration CreateAuthenticationConfiguration()
	{
		var authentication = new AuthenticationConfiguration
		{
			RequireSsl = false,
			EnableSessionToken = true
		};

		// Basic Authentication
		authentication.AddBasicAuthentication(_accountsService.ValidateAccountUsingSiteCredential);

		return authentication;
	}
}

Now, in the Global.asax file modify the Application_Start as follows

protected void Application_Start()
{
	AreaRegistration.RegisterAllAreas();

	//WebApiConfig.Register(GlobalConfiguration.Configuration);
	DependencyResolver.Current.GetService<WebApiConfig>().Register(GlobalConfiguration.Configuration);
	FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
	RouteConfig.RegisterRoutes(RouteTable.Routes);
	BundleConfig.RegisterBundles(BundleTable.Bundles);
}

That's it! You are good to go!

Enable CORS in Asp.net web.api using Thinktecture.IdentityModel

by sunil ravulapalli /24. August 2013 05:10 /asp.net-web-api /Comments (0)

Refer to http://sunilrav.com/post/Enable-Basic-Authetication-in-Aspnet-webapi-using-ThinktectureIdentityModel to enable basic authentication.
Add this method in WebApiConfig class

private static void ConfigureCors(HttpConfiguration config)
{ 
  var corsConfig = new WebApiCorsConfiguration(); 
  corsConfig.RegisterGlobal(config); 
   corsConfig
      .ForAllResources()
      .ForAllOrigins()
      .AllowAllMethods()
      .AllowAllRequestHeaders()
      .AllowAll();
}

Call ConfigureCors in Register method in WebApiConfig class

public static void Register(HttpConfiguration config)
{ 
  var authentication = CreateAuthenticationConfiguration();  
  config.MessageHandlers.Add(new AuthenticationHandler(authentication));   
  ConfigureCors(config); 
  config.Routes.MapHttpRoute(  name: "DefaultApi",  
           routeTemplate: "api/{controller}/{id}",  
           defaults: new { id = RouteParameter.Optional } );
  config.EnableSystemDiagnosticsTracing();
}

Make sure your web.config looks like this

<system.webServer> 
  <modules runAllManagedModulesForAllRequests="false">  
    <remove name="WebDAVModule" /> 
  </modules> 
  <handlers>  
    <remove name="WebDAV"/>  
    <remove name="OPTIONSVerbHandler"/>  
    <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />  
    <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />  
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />  
    <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> 
    <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />  
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> 
  </handlers>
</system.webServer>

Enable Basic Authetication in Asp.net web.api using Thinktecture.IdentityModel

by sunil ravulapalli /21. August 2013 04:55 /asp.net-web-api /Comments (0)

On Server

1. Install Thinktecture.IdentityModel from Nuget

2. In class WebApiConfig add the function CreateAuthenticationConfiguration() add Lines 1 and 2 like below

public static class WebApiConfig
{ 
    public static void Register(HttpConfiguration config) 
    {  
        var authentication = CreateAuthenticationConfiguration(); // Line 1 
        config.MessageHandlers.Add(new AuthenticationHandler(authentication)); // Line 2  
        config.Routes.MapHttpRoute(   name: "DefaultApi",   routeTemplate: "api/{controller}/{id}",  defaults: new { id = RouteParameter.Optional }  );         
        config.EnableSystemDiagnosticsTracing(); 
     }
     private static AuthenticationConfiguration CreateAuthenticationConfiguration() 
     {  
        var authentication = new AuthenticationConfiguration  
        {   
            RequireSsl = false,   EnableSessionToken = true  
        };  
        // Basic Authentication   
        authentication.AddBasicAuthentication((username, password) => username == "admin" && password == "password");  
        return authentication; 
     }
}

Lets say you have a ApiController like this

public class AccountsController : ApiController
{  
    [Authorize] 
    public AccountInformation Get(long id) 
    {  
         return new AccountInformation { AccountHolderName = "admin" }; 
    }
}

where

public class AccountInformation
{ 
    public string AccountHolderName { get; set; }
}

Run your Api project in visual studio and try to access
http://localhost:xxxxx/api/accounts/token

you should get dialog box asking for username and password. Here our username is "admin" and password is "password". You will then get the JSON response back which looks like this

{  
   "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...2KVb2HV3dP0tqN5NBzesdQhMc2J8Or-_RqaIRWLJpk4...........",  
   "expires_in": 36000.0
}

Now we know our Api stuff works.

How to call from a Client(Windows 8)

From the client the Login method looks like this

private async void Login_Click(object sender, RoutedEventArgs e)
{ 
   try 
   {  
      var credentials = new NetworkCredential("admin", "password");  
      var handler = new HttpClientHandler { Credentials = credentials };  
      var client = new HttpClient(handler) 
      {
        BaseAddress = new Uri("http://localhost:xxxxx/")
       };    
       var response = await client.GetAsync("api/accounts/token");                 
       response.EnsureSuccessStatusCode();  
       var accountInformationJson = await response.Content.ReadAsStringAsync(); 
       var json = JsonObject.Parse(accountInformationJson); 
       var token = json.GetNamedString("access_token");  
       var localSettings = ApplicationData.Current.LocalSettings; 
       localSettings.Values["sessionToken"] = token; 
    } 
    catch (HttpRequestException ex) { } 
    catch (Exception ex) { }
}

The function to get data after the login looks like this

try
{ 
   var localSettings = ApplicationData.Current.LocalSettings; 
   var sessionToken = localSettings.Values["sessionToken"]; 
   var client = new HttpClient() 
   { 
      BaseAddress = new Uri("http://localhost:xxxxx/") 
   }; 
   client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Session", sessionToken.ToString()); 
   var response = await client.GetAsync("api/accounts/123"); 
   response.EnsureSuccessStatusCode(); 
   var accountInformationJson = await response.Content.ReadAsStringAsync(); 
}
catch (HttpRequestException ex){ }
catch (Exception ex){ }

 References

http://leastprivilege.com/2012/06/19/session-token-support-for-asp-net-web-api/

http://ben.onfabrik.com/posts/dog-fooding-our-api-authentication

How to change you DNS pointer to point to you website on Azure from Discountasp.net

by sunil ravulapalli /10. August 2013 05:00 /azure /Comments (1)

On Discountasp.net
Once you log in, on left go to Tools and Utilities > DNS manager 

Find CNAME Record Manager section
Add www. and yourwebsite.azurewebsites.net
Add CNAME awverify to awverify.yourwebsite.azurewebsites.net

Find A record manager
Change yourwebsite.com IP to the one from Azure's Dashboard > Manage domains

Wait for DNS to propagate, these are some helpful websites to check DNS propagation
http://www.whatsmydns.net
http://www.digwebinterface.com/

On Azure
Go to Scale > General > Website mode > Switch to Shared
Dash board > Manage domains > Add www.yourwebsite.com and yourwebsite.com


 

My Digital Data With SkyDrive

by sunil ravulapalli /3. August 2013 01:17 /other /Comments (0)

I already upload all my documents such as word files and pdfs to SkyDrive. It gave me the convenience of accessing them through the browser on any computer. But, recently I decided to push all my Pictures, Videos and Music to SkyDrive. So, I no longer use my local hard disk for anything except installing applications. All my data is in the cloud!

I have five major machines I use:
 1. Samsung Laptop
 2. Surface Pro
 3. Acer Iconia W3
 4. Nokia Lumia 900
 5. Xbox

I use my laptop and my Surface Pro a lot. So, I installed the SkyDrive Desktop app on my laptop and on my Surface. So all the files sync seamlessly between them. I don't have to think about them. The files are just there where ever I need them. I can also add my SkyDrive folders to the Libraries in Windows explorer. For example, I add the SkyDrive Pictures folder to the Pictures Library, SkyDrive Music folder to the Music library and the SkyDrive Videos folder to the Videos library. This enables Windows Apps such as Pictures, Music, and Videos aware of the content. You can then use these Apps to stream you Music or Video to the Xbox though the magic of Smart Glass, so everybody in front of the TV can enjoy it! Just open the Smart Glass App and it establishes connection with the Xbox on the same network. Then open up the Music/Video/Picture App, in the Charms menu you will see a Devices option. Just click on it and choose the Xbox and connect, your content will start steaming to the Xbox.

Of Course, this has nothing to do with SkyDrive, imagine you are on your Laptop in your bedroom, you saved a picture on the SkyDrive, you want to show it others on your TV, all you have to do it bust out the Surface which is lying in front of the TV, open up the Pictures App make it display on the TV using the Xbox.

On a the Acer tablet, the Nokia phone and the Xbox, I really don't access files that much, however, in case I need my files I can do it easily with the Windows/Xbox store app, which gets me the files on demand.

Goods:
 The other benefits I foresee is that if I buy a new laptop in the future all my data will just come down once I install the SkyDrive desktop application. Although, I will still manually back up my laptop every month, once I get confident about the cloud, I am hoping I won't have to do any data backup in a few years. I am not really into the backup to an external drive on a schedule though some third party software thing. I like the cloud idea! If this really works, will we really need the Windows Media Server?

Bads:
 Cost? Although the free storage of 25G (I have a 10 year old account) will suffice for now, I might have to pay in the future. If there real benefits of my data everywhere with any major effort becomes true, then I don't mind paying for SkyDrive.

 

Step 6: Solution with Front End

by sunil ravulapalli /30. July 2013 00:35 /software-design /Comments (0)

Add Ninject binding to DataNinjectModule in the Data project.

public class DataNinjectModule : NinjectModule
{ 
  public override void Load() 
  {  
     Kernel.Bind<IUnitOfWork>().To<UnitOfWork>(); 
  }
}

Add Ninject binding to ServiceNinjectModule in the Data project.

public class ServiceNinjectModule : NinjectModule
{ 
  public override void Load() 
  {  
    Kernel.Bind<IWishlistService>().To<WishlistService>(); 
  }
}

Add a controller class in the Web project.

public class WishlistController : Controller
{ 
  private readonly WishlistService _wishlistService; 
  public WishlistController(WishlistService wishlistService) 
  {  
    _wishlistService = wishlistService; 
  } 
  public ActionResult Add() 
  {  
    return View(); 
  } 
  [HttpPost] 
  public ActionResult Add(WishListItemViewModel wishListItemViewModel) 
  {  
    _wishlistService.AddWishlistItem(wishListItemViewModel.Description, wishListItemViewModel.Quantity);  
    return RedirectToAction("All"); 
  } 
  public ActionResult All() 
  {  
    return View(_wishlistService.GetAllWishlistItems()); 
  }
}


Add a view model class.
Add corresponding views.
Modify routes
Add a connection string in Web.config.

<add name="CompanyDbContext" providerName="System.Data.SqlClient" connectionString="Data Source=MYMACHINE\SQLEXPRESS;Initial Catalog=Wishlist.Data.CompanyDbContext;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False" />

You can find the solution on GitHub.
https://github.com/sunilrav/Wishlist.6.SolutionWithFrontEnd


 

Step 5: Solution with a Service class

by sunil ravulapalli /12. July 2013 22:49 /software-design /Comments (0)

Add the Core, the Data project references to the Service project

Add interface IWishlistService to the Core project

public interface IWishlistService
{ 
   void AddWishlistItem(string description, int quantity); 
   IList<WishListItem> GetAllWishlistItems();
}

Add class WishlistService to to the Service project

public class WishlistService : IWishlistService
{ 
  readonly IUnitOfWork _unitOfWork; 
  public WishlistService(IUnitOfWork unitOfWork) 
  {  
     _unitOfWork = unitOfWork; 
  } 
  public void AddWishlistItem(string description, int quantity) 
  {  
      var wishListItem = new WishListItem  
      {   
            Description = description,   Quantity = quantity  
      };  
      using (_unitOfWork)  
      {   
         _unitOfWork.WishListItemRepository.Insert(wishListItem);   
         _unitOfWork.Save();  
      } 
  } 
  public IList<WishListItem> GetAllWishlistItems() 
  {  
     using (_unitOfWork)  
     {   
       return (List<WishListItem>)_unitOfWork.WishListItemRepository.GetAll();  
     }
  }
}

You can find the solution on GitHub.

https://github.com/sunilrav/Wishlist.5.SolutionWithService

Step 4: Solution with Unit of Work pattern

by sunil ravulapalli /5. July 2013 23:18 /software-design /Comments (0)

Add IGenericRepository the Core project

public interface IGenericRepository<T> where T : class
{ 
   void Insert(T entity); IEnumerable<T> GetAll();
}

Add IUnitOfWork to the Core project

public interface IUnitOfWork : IDisposable
{ 
   IGenericRepository<WishListItem> WishListItemRepository { get; } 
   void Save();
}

Add GenericRepository to the Data project

public class GenericRepository<T> : IGenericRepository<T> where T : class 
{ 
  readonly CompanyDbContext _context; 
  readonly DbSet<T> _dbSet; 
  public GenericRepository(CompanyDbContext context) 
  {  
     _context = context;  
     _dbSet = context.Set<T>(); 
  } 
  public void Insert(T entity) 
  { 
      _dbSet.Add(entity); 
  } 
  public IEnumerable<T> GetAll() 
  {  
     return _dbSet.AsEnumerable(); 
  }
}

Add UnitOfWork to the Data project

public class UnitOfWork : IUnitOfWork
{ 
   readonly CompanyDbContext _context; 
   public UnitOfWork() 
   {  
     _context = new CompanyDbContext(); 
   } 
   private bool _disposed; 
   protected virtual void Dispose(bool disposing) 
   {  
       if (!_disposed)  
      {   
          if (disposing)   
          {    
              _context.Dispose();   
          }  
      }  
      _disposed = true; 
    } 
    public void Dispose() 
    {  
      Dispose(true);  
      GC.SuppressFinalize(this); 
     }       
     public void Save() 
     {  
        _context.SaveChanges(); 
      } 
      public IGenericRepository<WishListItem> WishListItemRepository 
      {  
          get { return new GenericRepository<WishListItem>(_context); } 
      }
}

You can find the solution on GitHub.

https://github.com/sunilrav/Wishlist.4.SolutionWithUnitOfWork.git

Step 3: Solution with Entity Framework

by sunil ravulapalli /24. June 2013 22:08 /software-design /Comments (0)

Create wishlist item class in the Core project.

public class WishListItem
{ 
   public int Id { get; set; } 
   public string Description { get; set; } 
   public int Quantity { get; set; }
}

Add Entity framework using nuget to Data project.
Add reference to Core project in the Data project.
Create a context class in the Data project.

public class CompanyDbContext : DbContext
{ 
   public DbSet<WishListItem> WishListItems { get; set; }
}

Using the nuget console run "enable-migratons" for the Data project.
Also, using the nuget console run "update-database" for the Data project.

This will create the database in SQL express or LocalDb if the machine does not have SQL express. 


You can find the solution on GitHub.

https://github.com/sunilrav/Wishlist.3.SolutionWithEntityFramework.git
 

 

Step 2: Basic solution structure of an ASP.NET MVC in Visual Studio with Ninject

by sunil ravulapalli /15. June 2013 00:16 /software-design /Comments (0)

Add Ninject using Nuget to the Data and Service projects.

Add Ninject.Mvc3 using Nuget to the Web project.

In Data project add a class called DataNinjectModule which looks like this

using System;
using Ninject.Modules;
namespace Wishlist.Data.DependencyConfiguration
{    
    public class DataNinjectModule : NinjectModule    
    {        
       public override void Load()        
       {            
           throw new NotImplementedException();
        }
    }
}

In Service project add a class ServiceNinjectModule which looks like this

using System;
using Ninject.Modules;
namespace Wishlist.Service
{    
     public class ServiceNinjectModule : NinjectModule    
     {        
          public override void Load()        
          {            
                  throw new NotImplementedException();
          }    
     }
}

In Web project add these lines of code to the RegisterServices class in the NinjectWebCommon class found in the App_Start folder.(Substitute "Wishlist" with your project name)

kernel.Load("Wishlist.Data.dll");
kernel.Load("Wishlist.Service.dll");

You can find the solution on GitHub.

https://github.com/sunilrav/Wishlist.2.BasicSolutionWithNinject