How to mix Entity Framework with Web API - asp.net

I'm researching the new ASP.NET MVC4 Web API framework. I'm running Visual Studio 2011 beta on the Windows 8 consumer preview.
My problem is that none of the official samples for the new Web API framework use any kind of database backend. In the past, I've been able to create a local SQL CE database and serve it up via a WCF Data Service using Entity Framework as the ORM. How do I do the same with Web API?
Also, is this even a valid question? Should I just keep using a WCF Data Service if I want to expose an Entity Framework mapped SQL CE database? It seems to work fine, other than not offering the flexibility to choose response formatters that I might get with web api.

If you look at the official Contact Manager sample, you'll find that the Repository Pattern is used to access the data layer.
Also, bear in mind that in this particular example there's also DI via Ninject.
In my case I've easily plugged this onto an already existing EF model.
Here's an example for a repository implementation
///MODEL
public class SampleRepository : ISampleRepository
{
public IQueryable<Users> GetAll()
{
SampleContext db = new SampleContext();
return db.users;
}
[...]
}
///CONTROLLER
private readonly ISampleRepository repository;
public SampleController(ISampleRepository repository)
{
this.repository = repository;
}
//GET /data
public class SampleController : ApiController
{
public IEnumerable<DataDTO> Get()
{
var result = repository.GetAll();
if (result.Count > 0)
{
return result;
}
var response = new HttpResponseMessage(HttpStatusCode.NotFound);
response.Content = new StringContent("Unable to find any result to match your query");
throw new HttpResponseException(response);
}
}
Your mileage may vary though, and you might want to abstract out some of this data access even further.
Good news is that plenty of patterns and ideas that you may have already used on MVC-based projects are still valid.

I haven't worked with WCF Web API, so I can say for sure if you can use it same way as you did with WCF Web API, but I'm sure you can use EF with ASP.NET Web API. I suggest you take a look at how ASP.NET MVC makes use of EF, it should be very similar how you would use it with ASP.NET Web API.
As for other question, if you're planning some new development you should consider using ASP.NET Web API since there's an announcement on wcf.codeplex.com saying:
WCF Web API is now ASP.NET Web API! ASP.NET Web API released with
ASP.NET MVC 4 Beta. The WCF Web API and WCF Support for jQuery content
on this site will be removed by the end of 2012.

Related

Is it possible to restrict access to REST API built using Web API 2?

I built a REST API using ASP.NET Web API 2, so I could deliver data from a backend database to my applications running on any platform (mobile, web, desktop etc) However up until now, I simply call the website with the controller I need data from and that's it, it sends back the JSON string in the response.
But, the data is kind of special, and there is nothing to prevent another developer from simply calling the controllers and getting back the exact same data and building their own application around it.
My question is - is there anyway to restrict access to the API so that only my applications can get valid response from the server. (i.e. prevent other developers from using my REST API)
I already read these documentation Security, Authentication, and Authorization in ASP.NET Web API I'm just not sure which of these scenarios apply to me, or if any will do what I am asking.
EDIT - Another piece of info, my web service is running on Azure in case it is relevant.
Did you happen to check token based authentication?Please go through https://stackoverflow.com/a/38670221/4868839 and https://www.youtube.com/watch?v=rMA69bVv0U8 must be a good to start with.
there are different way to validate your web api.
Authentication Filters in ASP.NET Web API 2
using you can customise your authentication filter
you can refer sample Reference link
Token Based Authentication using ASP.NET Web API 2, Owin, and Identity
//App_Start/Startup class
public void ConfigureAuth(IAppBuilder app)
{
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/v1/accesstoken"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(AppConfiguration.AccessTokenExpireDuration),
Provider = new SampleOAuthProvider() // class that override your method
};
// Token Generation
app.UseOAuthBearerTokens(OAuthServerOptions);
}
You can find reference from inherits Default implementation of IOAuthAuthorizationServerProvider used by Authorization
i hope it sholud helps you thanks.

Client application login using httprequest

I am a bit new to ASP.NET and web development, and I am still confused about the following :
On the one hand I have a very complete ASP.NET MVC website based on NopCommerce that includes login, registration, e-commerce features, forums, etc.
On the other hand, I have a Windows Forms client application that needs to read and write data from and to my website database.
The first thing I would need to do is to allow users to login in the client application by sending a request to the server. I've been looking around the web for days and I can't manage to find a precise and secure way to do so.
I'm pretty much sure that I have to use System.Net.Http to make a request from the client. Will this request then got to be handled by a MVC controller action ? Maybe an already existing one ?
Here is the method I have so far, based on a tutorial found online (it is not complete at all) :
private static async void PostRequest(string addressPost)
{
IEnumerable<KeyValuePair<string, string>> queries = new List<KeyValuePair<string, string>>()
{
new KeyValuePair<string, string>("Query1", "Email"),
new KeyValuePair<string, string>("Query2", "Password")
};
HttpContent formContent = new FormUrlEncodedContent(queries);
using (HttpClient client = new HttpClient())
{
using (HttpResponseMessage response = await client.PostAsync(addressPost, formContent))
{
using (HttpContent content = response.Content)
{
string myContent = await content.ReadAsStringAsync();
System.Diagnostics.Debug.WriteLine(myContent);
}
}
}
}
Any existing example or help would be greatly appreciated.
first we need to focus on the architecture of the application, we have here two applications, 1) web application, 2) WinForm application. and you want to share the same db for both, here are the drawbacks of doing so, you might found yourself one day your winform will lock a table because of updating etc, and your web application will lose access, thats not a good idea,
here is how i would do it.
create a web api plugin for your web application, and use api tokens for security, there is some available web api plugin for nopcommerce but its limited in functionality, so i guess you will have to add some methods based on your needs, next thing you will do is have your winform application communicate with your webapi, in that case your winform works independently and secure,
as a side note, you can have in your web api multiple tokens for each user if you want, you can manage that in your web api plugin, just make a table where you will store that info with user info and tokens for everyone and you can manage that from the web admin.

WCFService's DBContext to MVC App?

I have created a 'WCFService' application under 'WCFSolution' solution and generated the DBContext using Entity Framework from a Database 'DemoDB' in 'WCFService' application. and also created some CRUD methods in WCFService (Which is working great).
Then I created an empty 'WCFMVCApp' MVC application under the same solution ('WCFSolution') and also added the service reference to this app. Now i needed to create a controller ('HomeController') with the DBContext that is generated in that WCFService, so that i can generate the views based on the WCF models while creating the controller.
I could create a new EF in WCFMVCApp but it would defeat the purpose of WCF. Any way to do this. or is it possible? Any help would be appreciated. Thank you.
If you are using a WCF Service, in your MVCProject you don't have a DbContext to deal with and you should not add a reference to your WCF Service. You have some options.
Solution 1: Use a client
In your MVC Project create a data service client. Your service should be running and you need the data service tools installed. Then you can add a service reference and some proxy classes are generated for you.
WCF Data Services 5.6.0 RTM Tools Installer
Solution 2: Add a DbContext dll
You can have your DbContext living in a seperate class library that you reference in your service and your MVC project.
In both cases you are using DataServiceContext to perform CRUD operations. For the second one you may have to add an an implementation for ResolveType. To get an idea how to do this, this is how the automatic generated DataServiceContext would resolve types:
ODataSamples
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.OData.Client.Design.T4", "2.1.0")]
public Container(global::System.Uri serviceRoot) :
base(serviceRoot, global::Microsoft.OData.Client.ODataProtocolVersion.V4)
{
....
this.ResolveType = new global::System.Func<string, global::System.Type>(this.ResolveTypeFromName);
....
}
/// <summary>
/// Since the namespace configured for this service reference
/// in Visual Studio is different from the one indicated in the
/// server schema, use type-mappers to map between the two.
/// </summary>
protected string ResolveNameFromType(global::System.Type clientType)
{
global::Microsoft.OData.Client.OriginalNameAttribute originalNameAttribute = (global::Microsoft.OData.Client.OriginalNameAttribute)global::System.Linq.Enumerable.SingleOrDefault(global::Microsoft.OData.Client.Utility.GetCustomAttributes(clientType, typeof(global::Microsoft.OData.Client.OriginalNameAttribute), true));
if (clientType.Namespace.Equals("ODataSamples.CustomFormatService", global::System.StringComparison.Ordinal))
{
if (originalNameAttribute != null)
{
return string.Concat("ODataSamples.CustomFormatService.", originalNameAttribute.OriginalName);
}
return string.Concat("ODataSamples.CustomFormatService.", clientType.Name);
}
return null;
}

Why is accessing session state and HttpContext in WebAPI considered bad design?

I have several .asmx web services that I want to upgrade to WebAPI. These web services look somewhat like this:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class TheWebService : System.Web.Services.WebService {
[WebMethod(EnableSession = true)]
public string SomeMethod(string SomeInput)
{
MySessionModel TheSession = HttpContext.Current.Session["UserSession"] as MySessionModel;
return SomeClass.SomeMethod(SomeInput, TheSession);
}
}
Basically, I have a single-page application. I'm using Forms Auth to login and redirect users to their "profile" and then, from this page, the app uses web services to communicate with the server. The web services only return raw strings so I don't need serialization at teh web service level. For the moment, the app is hosted in IIS and soon I'll be deploying it into azure.
I've looked around on the web, and several posts suggest that using session state and HttpContext is bad design. Why is using HttpCurrent and session state a bad idea in this case?
There is nothing innately wrong with using ASP.NET Session, as long as you don't use it as a catch-all basket for any old data. Shopping carts, for example, do not belong in Session: they belong in a Shopping Cart persistence component.
Also, and I suspect the reason for the Azure tag on this question, if you are running in a load-balanced environment such as an Azure Cloud Service, you need to use an external session provider such as a SQL Database or a shared cache. Using the in-process session provider (the default) will cause very odd, often unreproducable bugs as users are switched between different servers with different copies of the session.
As for HttpContext.Current, well, for Web API, things like Inversion of Control, Dependency Injection, and simple testability are important. A clean, testable Web API version of that service might look something like this:
public class TheWebService : ApiController {
private readonly IUserSession _userSession;
public TheWebService(IUserSession userSession)
{
_userSession = userSession;
}
public string SomeMethod(string SomeInput)
{
MySessionModel TheSession = _userSession.Get();
return SomeClass.SomeMethod(SomeInput, TheSession);
}
}
public interface IUserSession
{
MySessionModel Get();
}
You could still use HttpContext.Current.Session["UserSession"] in a class like this:
public class CurrentContextUserSession : IUserSession
{
public MySessionModel Get()
{
return HttpContext.Current.Session["UserSession"] as MySessionModel;
}
}
You would then use an IoC container such as Unity or Ninject to set CurrentContextUserSession as the implementation of IUserSession for Web API to use when constructing instances of TheWebService. But when you were writing your tests, you could use a mock or stub implementation of IUserSession that had no dependency on HttpContext.Current.
In your specific example, you are using the Session only inside the WebMethod, which is fine as it is already coupled to ASP.NET but many people tend to use this at other layers of their application which is a really bad design.
Common problems of using HttpContext.Current in those layers are:
the code cannot be easily unit tested in isolation
the code is tightly coupled to an ASP.NET context
This being said, having stateful services that depend on the session is bad design. In the example you have shown, that's an ASMX WebService which is depending on the ASP.NET Session state meaning that the client should be passing cookies around in order to invoke this service. Also stateful services are harder to scale.

SignalR Chat App in WinForm With Remote Clients

i am new in signalR , i have tried and learn from different web sites like github and etc etc
But i couldn't find the solution for my problem.... and now i am getting confused...
My problem is:
I have developed a Chat app in Winform with Web Services and Centralized Database and it is working fine in different countries as in different branches of one organization.
But i want to convert that Chat App into SignalR to achieve more efficiency but i couldn't understand , how to do it in SignalR. because All tutorials of SignalR on Web in one Solution.
like Web , Console or WinRT communicated with each other but they are in one solution but in my scenerio i cannot put the service or Web Page in WinForm application.
Please please help me out in this manner.
What you need to do is use the SignalR for .NET clients. Bring that into your project using NuGet assuming you are using Visual Studio.
You will need to import the following generally:
using Microsoft.AspNet.SignalR.Client;
using Microsoft.AspNet.SignalR.Client.Hubs;
Assuming you are following most of the tutorials on the web you can need the following to connect:
public IHubProxy Proxy { get; set; }
public HubConnection Connection { get; set; }
Also you will need to set the connection like so:
public string Host = "http://YourSignalRChatAppLocationOnAzureOrLocally.cloudapp.net/";
Connection = new HubConnection(Host);
//Assuming your SignalR hub is also called ChatHub (If you followed most tutorials it will be)
Proxy = Connection.CreateHubProxy("ChatHub");
This part will need to be in an async function:
//If you are passing an object back and fourth otherwise String is fine
Proxy.On<ChatMessage>("Send", hello => OnSendData("Recieved send " + hello.Username + " " + hello.Content));
await Connection.Start();
More material fro the link below, this guy has it running on Console app, WPF app, and web clients so you can see the difference.
Standard tutorial on how to make the web server.
SIGNALR MESSAGING WITH CONSOLE SERVER AND CLIENT, WEB CLIENT, WPF CLIENT

Resources