Implementing a WAP site using ASP.NET-MVC - asp.net-mvc

We plan on implementing a WAP site using ASP.NET-MVC.
Has anyone any experiance of this? Are there any Gotchas?
We will also be implementing a "standard" web site for browsers. Would it be possible to have a single set of Models and Controllers, and just have seperate views for each site?

It is possible to have for the most part a single set of models and controllers.
The way to do it will be via implementing the following Theming/Templating engine.
[Theming Support][1]
I piggy backed my solution on top of a Theming/Templating engine.
The major deviation from the article source is in the Global.asax.cs file where you need to add the following lines of code:
protected void Application_BeginRequest(Object Sender, EventArgs e)
{
SetTheme();
}
//this will set the responses Content Type to xhtml and is necessary as C# sends the WML response header
protected void Application_PreSendRequestHeaders(Object Sender, EventArgs e)
{
if (this.Context.Items["themeName"].ToString() == "xhtml")
{
this.Context.Response.ContentType = "application/vnd.wap.xhtml+xml";
}
}
private void SetTheme()
{
//set the content type for the ViewEngine to utilize.
HttpContext context = this.Context;
MobileCapabilities currentCapabilities = (MobileCapabilities)context.Request.Browser;
String prefMime = currentCapabilities.PreferredRenderingMime;
string accept = context.Request.ServerVariables["HTTP_ACCEPT"];
context.Items.Remove("theme");
context.Items.Remove("themeName");
if (accept.Contains("application/vnd.wap.xhtml+xml"))
{
context.Items.Add("themeName", "xhtml");
}
else if (prefMime == "text/vnd.wap.wml")
{
context.Items.Add("themeName", "WAP");
}
if (!context.Items.Contains("themeName"))
{
context.Items.Add("themeName", "Default");
}
}
I know I had to make a couple of code changes to make it MVC 1 compatible, but I can't remember the exact changes.
The other major problem I had was debugging the output. For this I used firefox with an extension ([User Agent Switcher][2]) that I've changed to add Accept Types to it.
For WAP2/XHTML1.2 the Accept Types are: text/html,application/vnd.wap.xhtml+xml,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Obviously you need your masterpage and content pages to adhere to WML or XHTML1.2
[1]: http://frugalcoder.us/post/2008/11/13/ASPNet-MVC-Theming.aspx Theming Support
[2]: http://chrispederick.com/work/user-agent-switcher/ User Agent Switcher

Related

Take an MVC web site offline and back online

I'm searching for a method to take a website offline with a message. I know about app_offline.htm, but I would like to do it programmatically.
Taking it offline is easy. I can generate app-offline.htm on root, but when I want web site to be back online it is not possible programmatically, because all services are down including images.
My project uses MVC (C#). For now I'm storing the site status in an SQL server database in a bit field.
I find a method to doing it with global.asax but I would like to see other solutions...
void Application_BeginRequest(object sender, EventArgs e)
{
if ((bool) Application["SiteOpenService"] == false)
{
if (!Request.IsLocal)
{
HttpContext.Current.RewritePath("/Site_Maintenance.htm");
}
}
}
ref:
http://www.codeproject.com/Tips/219637/Put-the-website-in-Maintanance-Mode-Under-Construc

How to detect mobile(not tablet) requests?

How can I detect mobile devices(but not tablets) requests in ASP.NET MVC application?
In ASP.NET, you can easily detect the mobile device request using Request.Browser.IsMobileDevice property and Request.UserAgent.
The following code checks the IsMobileDevice property and redirects to the mobile specific page:
protected void Page_Load(object sender, EventArgs e)
{
if (Request.Browser.IsMobileDevice)
{
Response.Redirec("~/default_mobile.aspx");
}
}
If you request "default.aspx" from mobile browser, it will redirect to default_mobile.aspx page
Read here where they explain in detail
Some times this may not work for some tablets
For that you have to use Request.Browser.ScreenPixelsWidth and validate against values of various screen sizes to achieve this . I think that will be the only way left to do it in the server side
If you want to trust client side javascript . There are varous scripts available to do that .
Check this Detect Mobile Browsers which may also help you .
As the other bloke said, you can use Request.Browser.IsMobileDevice
Either in your controller or in your layout page
Razor. You can do this in the layout page and it'll change depending on device e.g.
#if (Request.Browser.IsMobileDevice) {
}
Controller for an individual View e.g.
public ActionResult Index()
{
if (Request.Browser.IsMobileDevice)
return View("Index.Mobile");
else
return View();
}
An alternative is to use this API called 51Degrees.mobi. I personally haven't used it, but it looks pretty good and very complete: http://51degrees.codeplex.com/wikipage?title=MVC
Also, this has some more information on the subject of mobile detection. http://www.asp.net/whitepapers/add-mobile-pages-to-your-aspnet-web-forms-mvc-application

Using a WISON OR200 in web application ( MVC )

Few days ago i bought a WISON OR200 sensor for a web system that i am developing.
I used the SDK that sent to me the enterprise and was been testing in a window application and worked fine but i need it into a web application and i don´t know how to do it..
this is the windows form application:
WisSensorN WisObj = new WisSensorN(); // instance of wison object
objects in form:
private System.Windows.Forms.Button Enroll;
private System.Windows.Forms.Button Identify;
private System.Windows.Forms.PictureBox FingerPic;
private System.Windows.Forms.Button Stop;
private System.Windows.Forms.TextBox Status;
Load method() //Open() .DataEvent and SetDisplay are needed for the fingerprint
private void Form1_Load(object sender, EventArgs e)
{
WisObj.Open();
WisObj.DataEvent += new _IWisSensorNEvents_DataEventEventHandler(WisObj_DataEvent);
WisObj.SetDisplay((int)FingerPic.Handle);
// i can´t do WisObj.SetDisplay((int)FingerPic.Handle) on mvc web app
// because i can't get FingerPic object from view.
}
private void WisObj_DataEvent(WisSensorNLibLib.DATA data, string str)
{
switch (data)
{
case DATA.DATA_ENROLL:
// save the base 64 string of finger image
break;
case DATA.DATA_IDENTIFY_CAPTURE:
//validation
break;
case DATA.DATA_VERIFY_CAPTURE:
break;
}
}
private void Enroll_Click(object sender, EventArgs e)
{
WisObj.StartEnroll(); // it used for save the fingerprint
}
private void Identify_Click(object sender, EventArgs e)
{
WisObj.IdentifyCapture();
// it used to activate the sensor. When i did this on controller action,
// nothing happen. This is because the property setDisplay was not set
}
Any suggestions?
What can i do?
I asked to the company where i bought the fingerprint reader if have a SDK for web applications and never answered.
Help please!
Thnxs!
I think you are on a very wrong path. You can't simply use a device from a browser. The HTML/javascript 'application' that runs in the browser cannot connect to any local resource like I/O ports or Windows events. You will need special techniques, like ActiveX or Java applet to communicate with a device on a client machine.
Whether your website is MVC or plain ASP.NET or even PHP is irrelevant. If you don't know what ActiveX (and alumni) is used for and what drawbacks it has, you should look for a professional who can help you explain the situation and possibly develop a suitable solution.

ASP.NET MVC request context details

Where can I plug in a custom provider to set up the request context?
I want to run an ASP.NET MVC application in "slave" mode while gradually transitioning features from a legacy system. Each request will have a cookie, and I want to grab the cookie, make an external call to resolve it to a user identity, and set up that user identity for the remainder of the request.
I might set a forms authentication cookie, or use Session, but the source of truth about authentication has to be the externally-set cookie, on every request.
What's the best way to do this? Where do I plug in? I've looked at Authentication providers, and the Authorization attribute, but neither of those seems the right place for this.
I would have thought an HttpModule would be ideal for this scenario?
If I understand you correctly, I did something similar on a project I was working on recently:
public class UserSessionHttpModule : IHttpModule
{
private HttpApplication mApplication;
public void Dispose()
{
}
public void Init(HttpApplication context)
{
mApplication = context;
context.BeginRequest += new EventHandler(CheckUserSession);
}
private void CheckUserSession(Object sender, EventArgs e)
{
var extension = Path.GetExtension(mApplication.Context.Request.Path);
if (extension == "" || extension == ".aspx")
{
var userSessionService = ObjectFactory.GetInstance<IUserSessionService>();
userSessionService.CheckUserSession();
}
}
}
you could override the Init method in Global.asax page and listen to the PostAuthenticateRequest event, the events fires after authentication so you could change whatever values you like from the form authenticate cookies and inject your own

Extending Windows Authentication in ASP.NET MVC 3 Application

after a lot of googling and reading several solutions on how to manage mixed mode authentication in ASP.NET apps, I still have no fitting solution for my problem.
I've got to implement an intranet application for a bunch of different user groups. Until now i've used windows authenthication which was very simple to implement. My problems arise when it comes to authorizing usergroups for special application functionalities.
Using [Authorize(Users = "DOMAIN\\USER")] works great but due to that i have no access to the active directory managament, it is impossible to me to configure rolemanagement in the way I need it for my application.
What I'd like to do is defining custom roles and memberships in addition to the ones that are defined within the active directory (is such an extension possible? e.g. by implementing an own membershipprovider?).
What do you think is the best solution for my problem. Do I really have to implement a complex mixed mode authentication with forms authentication in addition to windows authentication?
Used Technologies:
MS SQL Server 2008
MS VS 2010
ASP.NET MVC 3 - Razor View Engine
Telerik Extensions for ASP.NET MVC
IIS 7 on Windows Server 2008
EDIT (final solution thanks to the help of dougajmcdonald):
After pointing me to use a custom IPrincipal implementation I've found some solutions here and here. Putting everything together I came to the following solution:
1.Create a custom principal implementation:
public class MyPrincipal: WindowsPrincipal
{
List<string> _roles;
public MyPrincipal(WindowsIdentity identity) : base(identity) {
// fill roles with a sample string just to test if it works
_roles = new List<string>{"someTestRole"};
// TODO: Get roles for the identity out of a custom DB table
}
public override bool IsInRole(string role)
{
if (base.IsInRole(role) || _roles.Contains(role))
{
return true;
}
else
{
return false;
}
}
}
2.Integrate my custom principal implementation into the application through extending the "Global.asax.cs" file:
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
if (Request.IsAuthenticated)
{
WindowsIdentity wi = (WindowsIdentity)HttpContext.Current.User.Identity;
MyPrincipal mp = new MyPrincipal(wi);
HttpContext.Current.User = mp;
}
}
3.Use my custom roles for authorization in my application
public class HomeController : Controller
{
[Authorize(Roles= "someTestRole")]
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
}
It works!!! yeah!
I'm not sure if this still applies in MVC, but in Webforms one way to do this would be as follows:
Create a new IPrincipal implementation perhaps extending WindowsPrincipal
In this class, give it a collection of roles (your own custom roles)
Populate those roles, by perhaps getting them from the DB.
Override IsInRole to return true if the role provided is EITHER true from the base call (WindowsAuthentication/Role) OR from your own custom role collection.
This way you can still hook into Principal.IsInRole("MyRole") and also the principal [PrincipalPermission()] annotation.
Hope it helps.
EDIT in answer to q's:
To integrate the principal into the authorisation you need to write your own method for OnAuthenticate in the global.asax for the type of authentication, so I would guess for you, something like this:
void WindowsAuthentication_OnAuthenticate(object sender, WindowsAuthenticationEventArgs e)
{
// ensure we have a name and made it through authentication
if (e.Identity != null && e.Identity.IsAuthenticated)
{
//create your principal, pass in the identity so you know what permissions are tied to
MyCustomePrincipal opPrincipal = new MyCustomePrincipal(e.Identity);
//assign your principal to the HttpContext.Current.User, or perhaps Thread.Current
HttpContext.Current.User = opPrincipal;
}
}
I believe Authorize came in at a later date to the PrincipalPermission, but I'm not too sure as to when/why of the differences I'm afraid :( - sorry!

Resources