Windows Mobile Support

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg
Showing posts with label view. Show all posts
Showing posts with label view. Show all posts

Friday, 10 February 2012

MVC - What a view should never contain( part 2)

Posted on 06:47 by Unknown
Part 1
Ieri am promis ca revin cu un post despre ce nu ar trebuii sa contina un view.
Pornim de la o clasa PersonModel care are urmatoarea definitie:
public class PersonModel
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
}
Pentru acest model avem urmatorul view:
@model PersonModel

@{
Layout = null;
}

<!DOCTYPE html>

<html>
<head>
<title>Person</title>
</head>
<body>
<fieldset>
<legend>PersonModel</legend>

<div class="display-label">Name</div>
<div class="display-field">
@Html.DisplayFor(model => model.Name)
</div>

<div class="display-label">Age</div>
<div class="display-field">
@Html.DisplayFor(model => model.Age)
</div>

<div class="display-label">Address</div>
<div class="display-field">
@Html.DisplayFor(model => model.Address)
</div>
</fieldset>
</body>
</html>
Mai tarziu apare o noua cerinta in aplicatie, ca sa se afiseze si coodonatele GPS a locatiei date. Pentru acest lucru se foloseste o adresa web care stie sa rezolve orice adresa. O implementare simpla este urmatoarea:
@model CIC.PersonModel
@{
Layout = null;

string coordLat;
string coordLong;

var request = WebRequest.Create(someAddress + "?location=" + Model.Address);
var webResponse = request.GetResponse();
using (var contentStream = new StreamReader(webResponse.GetResponseStream()))
{
var content = contentStream.ReadToEnd();
webResponse.Close();
string[] coords = content.Split(' ');
coordLong = coords[0];
coordLat = coords[1];
}
}
<!DOCTYPE html>
<html>
<head>
<title>Person</title>
</head>
<body>
<fieldset>
<legend>PersonModel</legend>
<div class="display-label">
Name</div>
<div class="display-field">
@Html.DisplayFor(model => model.Name)
</div>
<div class="display-label">
Age</div>
<div class="display-field">
@Html.DisplayFor(model => model.Age)
</div>
<div class="display-label">
Address</div>
<div class="display-field">
@Html.DisplayFor(model => model.Address)
</div>
<div class="display-label">
GPS Location</div>
<div class="display-field">
@coordLong
@coordLat
</div>
</fieldset>
</body>
</html>
Pagina functioneaza fara nici o problema doar ca in viewul face mult prea multe lucruri. Din el se face un request spre o alta componenta( serviciu), prin intermediul caruia se obtin coordonatele GPS a unei adrese, care se afiseza in view.
Modelul nu contine toate datele necesare pentru a afisa tot ce este necesar. Din aceasta cauza se ajunge sa se faca un apel spre o componenta externa. Nu are importanta daca aceasta componenta este un serviciu extern sau o clasa din assemblyul nostru. Toate datele necesare trebuie sa fie continute de catre model. Orice data trebuie sa ajunga in view prin intermediul modelului.
O solutie este sa adaugam doua propietati in PersonModel care sa reprezinte coordonatele GPS( sau putem sa ne cream o clasa care sa stocheze longitudinea si latitudinea - dar tot ca si o propietate din PersonModel o sa fie).
public class PersonModel
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
public string Longitude { get; set; }
public string Latitude { get; set; }
}
Inițializarea coordonatelor urmeaza sa fie mutata in controler. Problema de la care am pornit a fost rezolvata, insa ... apare un smell la orizont. Nu foarte puternic, dar extrem de periculos. Apelul spre serviciu se face direct din controler, cea ce nu e normal. Da, este adevarat ca controlerul ar trebuii sa pregateasca modelul, dar obtinerea coordonatelor ar trebuii sa se faca in alt loc. De exemlu putem sa scoatem acest apel intr-o alta clasa.
Read More
Posted in MVC, view | No comments

Thursday, 9 February 2012

MVC - What a view should never contain( part 1)

Posted on 07:16 by Unknown
Part 2
Suntem intr-o aplicatie MVC. Un model poate sa fie folosit de 1 sau mai multe viewuri.
Intrebarea de unde a pornit totul este Ce ar trebuii sa contina un view?
Daca ne luam dupa carte: Un View trebuie sa contina codul prin intermediul caruia se genereaza interfara grafica asteptata. Viewul se ocupa cu partea de render la date pentru a afisa modelul corespunzator.
In acest caz ce este un Model? Raspunsul scurt si sec pe care il primesc mereu este: o clasa care contine datele ce trebuie afisate in view.
Citisem anul trecut ca un model poate sa fie reprezentat de un web service, de un repository sau de catre un alt bussines layer. Aceasta afirmatie este falsa. Da sursa datelor poate sa fie un web-service, un repository sau un bussines layer, dar datele care o sa fie afisate tot ca o colectie de la 1 la n de de obiecte pe care le primim. Indifierent ca este o colectie de stringuri, o clasa, sau un singur string. Aceste date pot sa fie modelate ca si o clasa.
Daca ne intoarcem la prima afirmatie( modelul este o clasa) - putem sa schimbam raspunsul si sa spunem ca modelul este reprezentat de o colectie de date. In lumea ASP.NET MVC aceasta va fi mereu o clasa( da, chiar si un string este de fapt o clasa in .NET).
Si acuma pot sa pun intrebarea de unde a pornit totul.
Ce ar trebuii sa contina un View?
Doar codul prin intermediul caruia se face render la UI.
Dar daca trebuie sa formatam un element din model, aceast cod unde trebuie sa apara? In controler cand pregateste modelul sau in view. Ati spune ca depinde? Daca formatam un datetime atunci acest lucru s-ar putea face in view sau chiar in template. Daca formatam un obiect mai complex ar trebuii sa fie in controler. In al doilea caz avem o problema cu modelul. Modelul nu este in formatul de care avem nevoie, iar daca incercam sa refolosim un alt model, atunci mai bine ne facem un nou model cu datele de care avem nevoie.
Nu este nimic gresit sa avem cate un model pentru fiecare view. Este gresit sa avem un singur model la 20 de view-uri, iar modelul sa contina date care sa nu fie folosite de toate viewurile sau viewurile sa fie obligat sa faca procesare datelor pentru a putea afisa datele in formatul dorit.
Dar daca avem nevoie sa afisam date din model apeland un web-service. Niciodata sa nu puneti acest apel in view. In unele cazuri poate apelul sa fie facut din Java Script, dar niciodata din view. Genul acesta de logica nu are ce cauta in view.
Totul a pornit in momentul in care am vazut intr-un view un apel spre un web-service facut din C#.
Part 2
Read More
Posted in MVC, MVC 3, view | No comments

Thursday, 22 September 2011

MVC 3 - Custom view load based on the source of the request

Posted on 07:47 by Unknown
Pornim de la următoarea problema:
Se da o aplicație ASP MVC 3. Se dorește sa încarce view-uri custom pentru fiecare tip de device care o accesează. De exemplu în cazul în care request-ul vine de la un iPhone sau un Windows Phone 7 atunci view-urile care se încarcă o sa fie diferite.
MVC suporta deja crearea unei versiuni de view pentru mobile device, dar acest lucru nu o sa ne fie de ajuns. In funcție de rezoluție sau de brower o sa dorim sa încărcam view-uri total diferite. Informațiile despre ce tip de device accesează resursa le putem găsii in user-agent.
Proprietatea user agent-ul se poate găsii în următoarea locație
HttpContext.Request.UserAgent
Aceasta valoare o sa fie de tip string, unde este necesar sa cautam manual valoarea pe noi o cautam. Pentru IPhone user agent-ul o sa aibe valoarea:
Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3
Iar un request de la un Windows Phone 7 o sa aibe următoarea valoare:
Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0) Asus;Galaxy6
Sa presupunem ca o sa avem următoarea structura de fișiere sub directorul Views
Views
Home // Nume control
Index.cshtml
IPhone
Index.cshtml
WF7
Index.cshtml
Pentru a definii maparea la views-uri astfel încît sa fie rezolvate cu view-ul dorit este nevoie sa implementam interfața IViewEngine și sa ne definim un ViewEngine custom. In cadrul acestui ViewEngine pe metodele FindPartialView si FindView o sa fie nevoie sa verificam dacă user agent-ul este de la un anumit agent. In cazul în care request-ul vine de la un anumit device custom atunci este nevoie sa transmitem path-ul unde se găsește view-ul respectiv.
Altfel ajunge sa returnam o instanta noua a ViewEngineResult. Deoarece aceasta nu o sa conțină nici un view găsit, căutarea se va face in continuare în alt ViewEngine din colecție.
public class ApplePhoneViewEngine : IViewEngine
{
...
public ViewEngineResult FindPartialView(ControllerContext context, string viewName, bool useCache)
{
return context.HttpContext.Request.UserAgent.StartWith("iPhone)
? BaseViewEngine.FindPartialView(context, "IPhone/" + viewName, false)
: new ViewEngineResult(new string[] { });
}
...
}
Ne-a mai rămas sa înregistram view engine-ul pe care noi l-am definit mai sus. In Application_Start din Global.asax.cs este nevoie sa adaugăm următorul cod:
ViewEngines.Engines.Add(new ApplePhoneViewEngine());
Codul se poate refactoriza destul de frumos, dar va las pe voi sa faceți acest lucru. Daca doriți sa aflați mai multe informații puteți sa aruncați o privire aici: https://raw.github.com/gist/1077436/a35a62ce4be85ab439dacf44205792ca9ff2791d/customviewengine.cs
Read More
Posted in custom request, MVC 3, view | No comments
Older Posts Home
Subscribe to: Posts (Atom)

Popular Posts

  • E-Learning Vendors Attempt to Morph Mobile
    The sign should read: " Don't touch! Wet Paint !" I had a good chuckle today after receiving my latest emailed copy of the eLe...
  • Content Types - Level 6: Rich Media
    Level 6: Rich Media NOTE: This is part 7 of 7 and the conclusion of this continuing series; please see earlier posts for more background inf...
  • CDN is not the only solution to improve the page speed - Reverse Caching Proxy
    I heard more and more often think like this: “If your website is to slow, you should use a CDN.” Great, CDN is THE solution for any kind of ...
  • Publishing our CellCast Widget for iPad
    The rush has been on this week as our development team worked to design a new version of our CellCast Widget specifically for Apple's up...
  • NetCamp 2012 - Windows 8 development experience
    During this week I participate to NetCamp 2012.  This was the 6th NetCamp event and is organizing by Evensys. NetCamp is a dedicated event f...
  • SQL - UNION and UNION ALL
    I think that all of us used until now UNION in a SQLstatement. Using this operator we can combine the result of 2 queries. For example we wa...
  • Password/Token/PIN definition
    Password, Token, PIN, Passcode… every day we use this items when we need to authenticate in different systems. I observed that there are tim...
  • Shared Access Signature and URL encoding on Windows Azure
    Playing a little with Shared Access Signature was quite nice. In this moment this new functionality has a great potential. Playing a little ...
  • Content Types - Level 4: Reference
    Level 4: Reference Materials & Static Content NOTE: This is part 5 of 7 in a continuing series; please see earlier posts for more backgr...
  • Content Types - Level 5: Courseware
    Level 5: Content and Courseware NOTE: This is part 6 of 7 in a continuing series; please see earlier posts for more background information. ...

Categories

  • .NET
  • .NET nice to have
  • #if DEBUG
  • 15 iunie 2011
  • 15 octombrie 2011
  • 2011
  • abstracta
  • action
  • adaugare
  • ajax
  • Amsterdam
  • Android
  • aplicatii
  • App Fabric
  • Apple iSlate
  • array
  • as
  • ASP.NET
  • AsReadOnly
  • Assembly comun
  • async
  • Asynchronous programming
  • asyncron
  • Autofac
  • AutoMapper
  • az
  • Azure
  • Azure AppFabric Cache
  • Azure backup solution
  • Azure Storage Explorer
  • azure. cloud
  • backup
  • BCP utility
  • bing maps v7
  • BitArray
  • BlackBerry
  • blob
  • BlobContainerPublicAccessType
  • breakpoint
  • bucuresti
  • C#
  • cache
  • CallerMemberName
  • CellCast
  • Certificate
  • CES
  • change
  • ChannelFactory
  • clasa
  • classinitialize
  • clean code
  • click event
  • close
  • Cloud
  • Cluj
  • cluj-napoca
  • Code contracts
  • code retrat
  • codecamp
  • CollectionAssert
  • Compact Edition
  • compara
  • Comparer T .Default
  • CompareTo
  • comparison
  • comunitate
  • concurs
  • Conditional attribute
  • configurare
  • connection string
  • container
  • content type
  • control
  • Convert
  • convertAll
  • convertor
  • cross platform
  • CRUD
  • css
  • custom properties
  • custom request
  • DACPAC
  • Daniel Andres
  • data sync service
  • database
  • date time
  • datetime
  • debug
  • default
  • delegate
  • dependency injection
  • deploy
  • DeploymentItem
  • design patterns
  • Dev de Amsterdam
  • development stoage
  • dictionary
  • diferente
  • digging
  • director
  • Directory.Exist
  • disable
  • dispatcher
  • dispose
  • dropdown
  • dynamic
  • EF
  • email
  • encoding
  • entity framework
  • enum
  • enumerable
  • Environment.NewLine
  • error
  • error 404
  • error handling
  • eveniment
  • event
  • ews
  • excel
  • exception
  • exchange
  • exita
  • explicit
  • export
  • extension
  • field
  • File.Exist
  • finalize
  • fire and forget
  • Fluent interface pattern
  • format
  • func
  • GC.SuppressFinalize
  • generic
  • getdirectoryname
  • globalization
  • gmail
  • hackathon
  • Hadoop
  • handle
  • HTML
  • html 5
  • Html.ActionLink
  • http://www.blogger.com/img/blank.gif
  • HttpModule
  • IComparable
  • IE
  • ienumerable
  • IIS
  • image
  • implicit
  • import
  • int
  • internationalization
  • Internet Explorer
  • interop
  • Ioc
  • IP Filter
  • iPhone
  • iQuest
  • IStructuralEquatable
  • ITCamp
  • itspark
  • java script
  • javascript
  • July 2012
  • KeyedByTypeCollection
  • KeyNotFoundException
  • Kinect SDK
  • lambda expression
  • LightSwitch Microsoft Silverlight
  • linq
  • list
  • lista
  • lista servicii
  • liste
  • Live Connect
  • Live ID
  • load
  • localization
  • lock
  • m-learning
  • MAC
  • Mango
  • map
  • mapare
  • mapare propietati
  • messagequeue
  • meta properties
  • method
  • MethodImpl
  • Metro App
  • Microsoft
  • Microsoft Sync Framework
  • mlearning
  • mlearning devices
  • Mobile Apps
  • mobile in the cloud
  • mobile learning
  • mobile services
  • Mobile Web
  • mongoDb
  • monitorizare
  • msmq
  • multitasking
  • MVC
  • MVC 3
  • MVVM
  • namespace
  • nextpartitionkey
  • nextrowkey
  • Ninject
  • nivel acces
  • no result
  • normalize
  • nosql
  • null expcetion
  • null object pattern
  • NullReferenceException
  • OAuth API
  • office
  • offline
  • Open ID
  • openhackeu2011
  • operations
  • operator
  • optimization
  • option
  • outputcache
  • OutputCacheProvider
  • override
  • paginare
  • pagination
  • path
  • persistare
  • Portable Library tool
  • Post event – CodeCamp Cluj-Napoca
  • predicate
  • predictions
  • prezentare
  • process
  • proiect
  • property
  • propietati
  • query
  • ReadOnlyCollection
  • ReadOnlyDictionary
  • referinta
  • reflection
  • remote
  • reply command
  • request
  • request response
  • resouce
  • REST
  • REST Client
  • RESTSharp
  • ronua
  • rss
  • rulare
  • salvare in fisier
  • sc
  • schimbare timp
  • select
  • select nodes
  • send
  • serializare
  • serialization
  • Server.Transfer. Resposen.Redirect
  • service bus
  • ServiceBase
  • servicecontroller
  • sesiune
  • session
  • Session_End
  • Session_Start
  • setup
  • Sibiu
  • signalR
  • Silverlight
  • sincronizare
  • Single Responsibility Principle
  • SkyDrive
  • skype
  • smartphones
  • smtp
  • Snapguide
  • sniffer
  • socket
  • solid
  • spec#
  • sql
  • Sql Azure
  • SQL CE
  • sql server 2008 RC
  • SRP
  • startuptype
  • stateful
  • stateless
  • static
  • stergere
  • store
  • store procedure
  • stream
  • string
  • string.join
  • struct
  • StructuralEqualityComparer
  • submit
  • switch
  • Symbian
  • Synchronized
  • system
  • tabele
  • table
  • techEd 2012
  • tempdata
  • test
  • testcleanup
  • testinitialize
  • testmethod
  • thread
  • timer
  • ToLower
  • tool
  • tostring
  • Total Cost Calculator
  • trace ASP.NET
  • transcoding
  • tuplu
  • tutorial
  • TWmLearning
  • type
  • unit test
  • unittest
  • UrlParameter.Optional
  • Validate
  • validation
  • verificare
  • video
  • view
  • ViewBag
  • virtual
  • visual studio
  • VM role
  • Vunvulea Radu
  • wallpaper
  • WCF
  • WebBrower
  • WebRequest
  • where clause
  • Windows
  • windows 8
  • Windows Azure
  • Windows Azure Service Management CmdLets
  • windows live messenger
  • Windows Mobile
  • Windows Phone
  • windows service
  • windows store application
  • Windows Task
  • WinRT
  • word
  • workaround
  • XBox
  • xml
  • xmlns
  • XNA
  • xpath
  • YMesseger
  • Yonder
  • Zip

Blog Archive

  • ▼  2013 (139)
    • ▼  November (17)
      • Service Bus - Optimize consumers using prefetch an...
      • Extract relative Uri using MakeRelativeUri method
      • Sync Group - Let's talk about Performance
      • [PostEvent] Slides from MSSummit 2013, Bucharest
      • How to get the instance index of a web role or wor...
      • Sync Group - A good solution to synchronize SQL Da...
      • Throttling and Availability over Windows Azure Ser...
      • How to monitor clients that access your blob storage?
      • Digging through SignalR - Dependency Resolver
      • [Event] Global Day of Coderetreat in Cluj-Napoca! ...
      • Windows Azure Service Bus - What ports are used
      • Debugging in production
      • Simple load balancer for SQL Server Database
      • [PostEvent] MSSummit 2013, Bucharest
      • How to read response time when you run a performan...
      • VM and load balancer, direct server return, availa...
      • Bugs that cover each other
    • ►  October (12)
    • ►  September (10)
    • ►  August (7)
    • ►  July (8)
    • ►  June (15)
    • ►  May (12)
    • ►  April (17)
    • ►  March (16)
    • ►  February (9)
    • ►  January (16)
  • ►  2012 (251)
    • ►  December (9)
    • ►  November (19)
    • ►  October (26)
    • ►  September (13)
    • ►  August (35)
    • ►  July (28)
    • ►  June (27)
    • ►  May (24)
    • ►  April (18)
    • ►  March (17)
    • ►  February (20)
    • ►  January (15)
  • ►  2011 (127)
    • ►  December (11)
    • ►  November (20)
    • ►  October (8)
    • ►  September (8)
    • ►  August (8)
    • ►  July (10)
    • ►  June (5)
    • ►  May (8)
    • ►  April (9)
    • ►  March (14)
    • ►  February (20)
    • ►  January (6)
  • ►  2010 (26)
    • ►  December (1)
    • ►  November (1)
    • ►  October (1)
    • ►  June (2)
    • ►  May (1)
    • ►  April (4)
    • ►  March (1)
    • ►  February (1)
    • ►  January (14)
Powered by Blogger.

About Me

Unknown
View my complete profile