15 09 2014

Android Tips - Formatting Text with Html Tags

Android Tips #1


Formatting Text with Html.fromHtml()


Android gives you the possibility to easily format text with HTML markup. 

Supported HTMLTags
TagsFormat
b, strongBold
i, em, cite, dfnItalics
uUnderline
subSubtext
supSupertext
bigBig
smallSmall
ttMonospace
h1 … h6Headlines
imgImage
fontFont face and color
blockquoteFor longer quotes
aLink
div, pParagraph
brLinefeed

Formatting text from your strings.xml

If you want to support text formatting from within your strings.xml file, you have to escape the tags – or use a CDATA section. Otherwise Android simply ignores them when reading the resource file.
To escape the tags you just need to replace all "<" characters. Luckily you do not have to escape the ">" characters as well. That way the HTML structure is still at least kind of readable. But only kind of.
If you use many HTML tags a CDATA section is better. For the sample above it looks like this:
1<string name="htmlFormattedText">
2      <![CDATA[
3      Text with markup for bold
4      and italic text.
5      There is also support for a
6      teletype-style font.
7      But no use for the code
8      tag!
9      ]]></string>
Even if you can add a lot of HTML tags, you are better off using only minor styling as mixing too much styles makes your text look uneasy instead of being more striking.
The following snippet shows how to use this string from within your Java code:
1TextView view = (TextView)findViewById(R.id.sampleText);
2String formattedText = getString(R.string.htmlFormattedText);
3Spanned result = Html.fromHtml(formattedText);
4view.setText(result);

Alternatives to consider

For longer texts that use HTML tags, I recommend to use raw files instead.
For more complicated formatting a WebView probably would be better.

8 03 2014

How To Clone A Generic List in C#

static class Extensions
{
    public static IList<T> Clone<T>(this IList<T> listToClone) where T: ICloneable
    {
        return listToClone.Select(item => (T)item.Clone()).ToList();
    }
}

5 07 2013

Cross Side Request Forgery attack nedir? [Anti Forgery in MVC]

CSRF (Cross Side Request Forgery) aynı zamanda XSRF olarak da kısaltılmıştır. Şu şekilde kısa ifade edebiliriz, bir saldırganın siteniz üzerindeki açık servisleri kullanarak (RESFTful), verilerinize erişip değiştirebilmesi, silebilmesi veyahut veri yazabilmesi mümkündür.

 Bunun önüne geçilebilmesi için ajax methodları için yazdığımız servisleri yetkilendirmeye tabi tutacağız, bunu da sitemizi barındırdığımız IIS üzerinde bir machine key oluşturup, sitemiz dahilinde bu servisi kullanan sayfada bu key ile kriptolanmış bir token oluşturup istemcinin makinasına cookie ile atacağız, daha sonra gelen her istekte bu tokenı okuyarak karşılaştıracağız ve açık ajax methodları (webapi restful servisler) güvenli hale getirilmiş olacak.

Tüm bu token oluşturma, cookie oluşturma vs. işlerini her sayfada biz değil de bizim yerimize Microsoftun getirmiş olduğu Antifoırgery token sistemi yapacak.

Şimdi uygulamalı örneğimizle daha iyi açıklayalım;

Otel listesi dönen view;
HotelList.cshtml
@{
    ViewBag.Title = "Hotel List";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
@Html.AntiForgeryToken()
<< formumuzun arama butonu, webapi controllera çağrıda bulunur.
 viewımız her ne kadar GET methodu kullansada bir form ve tokenı değerini üretip sayfaya bir hidden field ile basacak olan
@Html.AntiForgeryToken()​ fonksiyonunu ekledik. sayfa render edildiğinde sayfa kaynağında aşağıdaki gibi bir token eklendiğini görürüz,
<form id="__AjaxAntiForgeryForm" action="#"><input name="__RequestVerificationToken" type="hidden" value="AcKivtXxcbUSPqyNM9FC1N2Olunc3IWK6tZPxr3rTeOTikbFOPb3NCJiL5pwZEW9xk9E7JmuP3KDdTaUCxc3MYWbUycnbbWWIr9Gi-TFaFbgVt9xIRCiAs9LHG3-hwSgclziMQ2" /></form>

Şimdi webapi controller ımıza antiforgery token validate ettirecek atrribute ekleyelim,


    [ValidateHttpAntiForgeryToken]
    public class TApi1Controller : ApiController
    {
           // GET api/tapi1
        public IEnumerable GetHotelList() 
        {
            var hotels = BusinessLayer.DataProvider.GetHotelList("", "", "", 1, 0);
            return hotels;
        }

Projemize Filters adında yeni bir klasör yaratalım, ve antiforgery validate edecek olan attribute classımızı ekleyelim,

public class ValidateHttpAntiForgeryTokenAttribute : AuthorizationFilterAttribute
    {
        public override void OnAuthorization(HttpActionContext actionContext)
        {
            HttpRequestMessage request = actionContext.ControllerContext.Request;
            try
            {
                var cookie = request.Headers
               .GetCookies()
               .Select(c => c[AntiForgeryConfig.CookieName])
               .FirstOrDefault();
                AntiForgery.Validate(cookie != null ? cookie.Value : null, request.Headers.GetValues("__RequestVerificationToken").FirstOrDefault());
            }
            catch (HttpAntiForgeryException e)
            {
                actionContext.Response = request.CreateErrorResponse(HttpStatusCode.Forbidden, e);
            }
        }

Ve son olarak ajax methodumuzu çağıran javascript dosyamıza gerekli düzenlemeyi yapıyoruz,

var token = $('[name=__RequestVerificationToken]').val();
var headers = {};
headers["__RequestVerificationToken"] = token;

function GetHotelSearchList() {
    jQuery.support.cors = true;
    $.ajax({
        url: 'http://mydomain/GetHotelList',
        type: 'GET',
        contentType: "application/json;charset=utf-8",
        cache: false,
        headers: headers,
        success: function (data) {
            WriteResponseHotelList(data);
        },
scriptte görüldüğü üzere, token değerini header olarak ajax requestimize ekleyip sunucuya gönderiyor ve validate edilmesini sağlıyoruz, bunu yapmazsak istenen responseu vermeyecek ve header error dönecektir.
Ürettiğimiz token, session bazlı cookie oluşturur, token değerini web.config system.web altında de belirteceğimiz machineKey tag ile belirteceğiz,
 <machineKey validationKey="C155B0F32216020427A11841A17E9792B1FD7AAB7B0916EDF334788BCDFD1FB96093D1FD2AA94D270C6FFD47E55178549143623E435773732D67C16F78974059" decryptionKey="AD4A4DB683704373A30CF9BA109EFB13C0DA5E2345823905F61BBBD56BD3F12B" validation="SHA1" decryption="AES" />
</system.web>  
machineKey üretmek için şu adresi kullanabilirsiniz,
http://aspnetresources.com/tools/machineKey
Artık CSRF attack larına karşı güvendeyiz, sitemizi test ettikten sonra saldırıya karşı nasıl cevap verdiğini görmek için test amaçlı olarak şu kısmı kapatıp sabit bir değer vermeyi deneyin resimdeki gibi hata verecektir ,

<form id="__AjaxAntiForgeryForm" action="#"><input name="__RequestVerificationToken" type="hidden" value="fBoEFIJVpx8kdsgD0l9jWQI0sTKr2aZkeFyLlt143IOwfMDBKhGFFzNUFD7sdsuxGkVVd51-jhB8ZFIc7hkfj2Apuik_bAaQ94xp7hwOb_CCPrRvhAzMwK04-ZWEHVsS0hStRQ2" /></form>
 
Önlemin çalıştığından emin olduktan sonra tekrar eski haline çevirip kaydetmeyi unutmayalım,
@Html.AntiForgeryToken()

Herkese iyi çalışmalar dilerim.
Mücahid Uslu

Share It