ViewState ve Güvenliği

ASP.NET ile uygulama geliştirmiş kişiler ViewState ile mutlaka tanışmışlar ve bir fikirleri olmuştur. Bu makalede ViewState’in aslında ne olup ne olmadığını hangi amaçlar için kullanılması gerektiğini ve nasıl daha verimli bir şekilde kullanılabileceğini anlatacağım biraz daha üst seviyede anlatacağım.

ViewState Ne Değildir?
İlk olarak ViewState’in ne olmadığını anlatalım. ViewState’in post edilen değerlerin form kontrollerine tekrar yerleştirilmediğine dair yanlış anlamalar vardır. Bunu görmek için en basit yol sayfanızdaki viewstate kontrollerini disable etmeniz ve bu web kontrollerin değerlerinin tekrar yerine konulup konulmadığını seyretmenizdir. Bu web kontrolleri sadece sayfa ilk yüklenirken (!Page.IsPostBack) yaratılmasına rağmen, sayfadaki web kontollerinin değerlerinin sayfa postback edilirken de yerine konulması otomatik olarak yapılır. Sayfadaki web kontrollerinin değerlerinin tekrar yerine otomatik olarak konulması ViewState’in yaptığı tek şey değildir.

ViewState kod içerisinde dinamik olarak yaratılan herhangi bir kontrolü tekrar otomatik olarak yaratmaz. Kod içerisinde dinamik olarak yarattığınız bu kontrolü kullanmak istiyorsanız kod içerisinde tekrar yaratmalısınız. Eğer bu tip bir kod yazdıysanız bu işlem biraz zor olabilir, özellikle bir event içinde yarattıysanız. Fakat bu, her Load sırasında daha önce yaptığınız veya tekrar yarattığınız dinamik kontrolün bilgisini ViewState’de tutarak yapılabilir. Fakat bunu manuel olarak kod içerisinde yapmalıyız.

Sonuç olarak, ViewState sizin için veya oturum verileri (Session Data) veya sayfalar arası veri transferleri için değildir. ViewState sadece o anki sayfayla ilgili olan durum datası ve sayfanın çeşitli kontrolleri için dizayn edilmiştir. Herhangi bir durumda ViewState yeni bir sayfaya yollanamaz, redirect edilemez veya server transfer yapılamaz. Eğer bir çok sayfa arasında veri transferi yapmak istiyorsanız, Cookie ya da Session nesnelerini kullanabilrisiniz. Ama ViewState’lerin amacı bu değildir. ViewState birazdan göreceğiniz gibi güvenli değildir ve sistem kaynaklarını verimli kullanabilmek için en iyi yöntem değildir.


ViewState Nedir?
ViewState sayfada bulunan web kontrollerinin değerlerini tekrar yerine koymak veya bu değerleri izlemek için kullanılır. Bu değerler form ile birlikte post edilmediği için ya da bu web kontolleri HTML sayfası içinde olmadığından kaybolurlar. Bu herhangi bir kontolün tamamiyle HTML içinde tanımlandığı anlamına gelir. Eğer kod içerisinde bu kontroller üzerinde bir değişiklik yapmayacaksak ViewState’e ihtiyacımız da olmaz. ViewState sadece herhangi bir şekilde kod içerisinde, data-binding’de ya da kullanıcı etkileşimlerinde dinamik olarak değişen bu kontollerin değerlerini tutar.

Böylece ViewState kod içerisinde yaptığınız değişikliklerin özelliklerini, kontole bağladığınız datayı ya da PostBack işlemi ile birlikte kullanıcının yaptığı işlemler sonucunda ortaya çıkan yeni durumun bilgisini tutar. Örnek olarak, kullanıcı sayfanın PostBack olmasına neden olacak Calendar nesnesinden bir değeri seçsin. Seçim yapıldıktan sonra ortaya çıkan calendar’ın yeni özellikleri yeniden yerine konulana kadar Calendar’ın ViewState’inde tutulacaktır, fakat özellikler bir dahaki sefere post edilmeyecektir.

ViewState’in Formatı
ViewState sayfa içinde __VIEWSTATE adında gizli bir form elemanı olarak yer alır. Bu gizli form elemanının değeri Base64 ile kodlanmıştır bu yüzden okunabilirliği kolay değildir. Base64 ile kodlanmıştır ama şifrelenmemiştir.Bu iki kavram karıştırılmamalıdır. __ViewState’de tutulan bilgileri Machine.config dosyasında, Web.config dosyasında veya sayfa düzeyinde “enableViewStateMac” özelliğini değiştirerek şifrelenmesini sağlayabilirsiniz.

machine.config or web.config:
page level directive:
page level script code: Page.EnableViewStateMac = false;

__ViewState’deki bilgileri isteğe bağlı olarak değişik şekillerde şifreleyebilirsiniz. Bunu Machine.config dosyasındaki machineKey’in validation değerini değiştirerek yapabilirsiniz. Eğer validation değerine yazdığınız string ifadesine göre ViewState’deki bilgilerin şifrelenmesini istiyorsanız enableViewStateMac özelliğinin ”true” olarak değiştirilmesini unutmayın.

machine.config:

Fakat makine seviyesinde bu ayarın yapılması daha fazla kaynak kullanımını doğurur bu da tavsiye edilmeyen bir durumdur.

Yukarıdakiler ek olarak; ViewState render işlemi yapılmadan önce Page.SavePageStateToPersistenceMedium metodu ile kaydedilir ve PostBack işlemi sırasında Page.LoadPageStateFromPersistenceMedium metodu ile tekrar sayfaya yüklenir.

protected override object LoadPageStateFromPersistenceMedium()
{
return Session["ViewState"];
}
protected override void SavePageStateToPersistenceMedium(object viewState)
{
Session["ViewState"] = viewState;
// Session’a atasanız bile sayfada hidden olarak __ViewState bulunmalıdır.
RegisterHiddenField("__VIEWSTATE", "");
}

Bu iki metot kolay bir şekilde override edilerek Session’a atılabilir. Bu yöntem default olarak Session kullanan mobil araçlarda daha az bandwith’in kullanılması gerektiği durumlarda yararlı olur. Diğer veri ambarlarında database, gelişmiş Session yöntemleri gibi, ViewState’i saklamak için özel LosFormatter sınıfını kullanarak seralization and deserialization işlemlerini gerçekleştirmek gerekir.

protected override object LoadPageStateFromPersistenceMedium()
{
LosFormatter format = new LosFormatter();
return format.Deserialize(YourDataStore["ViewState"]);
}
protected override void SavePageStateToPersistenceMedium(object viewState)
{
LosFormatter format = new LosFormatter();
StringWriter writer = new StringWriter();
format.Serialize(writer, viewState);
YourDataStore["ViewState"] = writer.ToString();
}

KAYNAK : http://aspalliance.com/articleViewer.aspx?aId=135&pId=


http://www.aspnedir.com/Article/DisplayArticle.aspx?ID=603

Don’t run production ASP.NET Applications with debug=”true” enabled

One of the things you want to avoid when deploying an ASP.NET application into production is to accidentally (or deliberately) leave the switch on within the application’s web.config file.

Doing so causes a number of non-optimal things to happen including:

1) The compilation of ASP.NET pages takes longer (since some batch optimizations are disabled)
2) Code can execute slower (since some additional debug paths are enabled)
3) Much more memory is used within the application at runtime
4) Scripts and images downloaded from the WebResources.axd handler are not cached

This last point is particularly important, since it means that all client-javascript libraries and static images that are deployed via WebResources.axd will be continually downloaded by clients on each page view request and not cached locally within the browser. This can slow down the user experience quite a bit for things like Atlas, controls like TreeView/Menu/Validators, and any other third-party control or custom code that deploys client resources. Note that the reason why these resources are not cached when debug is set to true is so that developers don’t have to continually flush their browser cache and restart it every-time they make a change to a resource handler (our assumption is that when you have debug=true set you are in active development on your site).

When is set, the WebResource.axd handler will automatically set a long cache policy on resources retrieved via it – so that the resource is only downloaded once to the client and cached there forever (it will also be cached on any intermediate proxy servers). If you have Atlas installed for your application, it will also automatically compress the content from the WebResources.axd handler for you when is set – reducing the size of any client-script javascript library or static resource for you (and not requiring you to write any custom code or configure anything within IIS to get it).

What about binaries compiled with debug symbols?

One scenario that several people find very useful is to compile/pre-compile an application or associated class libraries with debug symbols so that more detailed stack trace and line error messages can be retrieved from it when errors occur.

The good news is that you can do this without having the have the switch enabled in production. Specifically, you can use either a web deployment project or a web application project to pre-compile the code for your site with debug symbols, and then change the switch to false right before you deploy the application on the server.

The debug symbols and metadata in the compiled assemblies will increase the memory footprint of the application, but this can sometimes be an ok trade-off for more detailed error messages.

The Switch in Maching.config

If you are a server administrator and want to ensure that no one accidentally deploys an ASP.NET application in production with the switch enabled within the application’s web.config file, one trick you can use with ASP.NET V2.0 is to take advantage of the section within your machine.config file.

Specifically, by setting this within your machine.config file:







You will disable the switch, disable the ability to output trace output in a page, and turn off the ability to show detailed error messages remotely. Note that these last two items are security best practices you really want to follow (otherwise hackers can learn a lot more about the internals of your application than you should show them).

Setting this switch to true is probably a best practice that any company with formal production servers should follow to ensure that an application always runs with the best possible performance and no security information leakages. There isn’t a ton of documentation on this switch – but you can learn a little more about it here.

Hope this helps,

Scott

Updated: Tess has a great follow-up post with more details about what happens when debug="true" is enabled. You can read it here.


http://weblogs.asp.net/scottgu/archive/2006/04/11/442448.aspx

SQL SERVER 2005 - Generate Script with Data from Database – Database Publishing Wizard

http://blog.sqlauthority.com/2007/11/16/sql-server-2005-generate-script-with-data-from-database-database-publishing-wizard/

the folder contains sqlsubwiz.exe:
C:\Program Files\Microsoft SQL Server\90\Tools\Publishing\1.2

on the command prompt;
type cd C:\Program Files\Microsoft SQL Server\90\Tools\Publishing
type sqlpubwiz script -d AdventureWorks AdventureWorks.sql

How to: Set the Culture and UI Culture for ASP.NET Web Page Globalization

Notably, when adding globalization to web.config, it needs to be within system.web

e.g.

< system.web >
< uiculture="en" culture="en-US">
< / system.web >

http://msdn.microsoft.com/en-us/library/bz9tc508.aspx

ve default culture için kullanacağın resx dosyası culture bilgisi içermemeli. örn:

TopMenu.ascx.resx


< globalization requestEncoding="iso-8859-9" responseEncoding="iso-8859-9" fileEncoding="responseEncoding="iso-8859-9" uiCulture="en" culture="en-US" / >

tr karakterlerin görüntülenebilmesi için: iso-8859-9
uiculture / culture default language için.

creating and editing resx files at runtime

RESX file Web Editor

http://blog.lavablast.com/post/2008/02/RESX-file-Web-Editor.aspx

http://www.enespekkaya.com/resx-resource-dosyalarinin-icerigini-duzenlemek-veya-yenisini-olusturmak-bolum-1/

HTTP Compression Module

http://www.codeproject.com/KB/aspnet/httpcompression.aspx

A compression module for ASP.NET that works with WebResource.axd, JavaScript, and CSS

GZip vs. Deflate - Compression and Performance

After I wrote about a HTTP compression module in ASP.NET 2.0 one of my colleagues pointed out that the Deflate compression is faster than GZip.

Because the HTTP compression module chooses GZip over Deflate if the browser allows it, I thought that I'd better make a quick performance test just to be sure. I used this little test method to give me the answer I was looking for:

using System.IO.Compression;
using System.IO;
using System.Diagnostics;

private void PerformanceTest()
{
byte[] buffer = new byte[5000];
using (MemoryStream stream = new MemoryStream())
{
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 1000; i++)
{
GZipStream gzip = new GZipStream(stream, CompressionMode.Compress);
gzip.Write(buffer, 0, buffer.Length);
}

sw.Stop();
Response.Write(sw.ElapsedMilliseconds);
}
}

First I tested the GZipStream and then the DeflateStream. I expected a minor difference because the two compression methods are different, but the result astonished me. I measured the DeflateStream to 41% faster than GZip. That's a very big difference. With this knowledge, I'll have to change the HTTP compression module to choose Deflate over GZip.

http://www.webpronews.com/expertarticles/2006/12/08/gzip-vs-deflate-compression-and-performance

recursive function

private void BindMenu()
{
if (TreeView1.Nodes.Count == 0)
{
IntertechDBDataContext db = new IntertechDBDataContext();
var pages = db.Pages;

foreach (Page page in pages.Where(p => p.ParentPageID == null))
{
TreeNode node = new TreeNode();
node.Value = page.PageID.ToString();
node.Text = page.Title;
node.NavigateUrl = "~/Admin/Page/Details.aspx?id=" + node.Value;
TreeView1.Nodes.Add(node);

BindChilds(node, page.Pages);
}
}

private static void BindChilds(TreeNode parentNode, EntitySet childs)
{
if (childs.Count > 0)
{
foreach (Page page in childs)
{
TreeNode node = new TreeNode();
node.Value = page.PageID.ToString();
node.Text = page.Title;
node.NavigateUrl = "~/Admin/Page/Details.aspx?id=" + node.Value;
parentNode.ChildNodes.Add(node);

BindChilds(node, page.Pages);
}
}
}

DTO - not only for web services

Usually developers think that DTO (Data Transfer Object) is something related to web services where data serialization is required to move data from one point of network to another. It is clear that in most cases there is no point to move complex data structures over network when client side needs this data in pretty simple form. That's why DTOs are created - they are simple, easily serializable and there is no data that client side doesn't need. But there are also other DTOs you may find useful.

User Interface DTOs

User Interface (UI) may also need some DTOs. By example, data bound controls try usually to save bounded data to their ViewState. But what happens when data source is list on some objects and not DataTable as we can usually see from beginner tutorials? DataTable is serializable and therefore it is easy to save DataTable to ViewState. But objects are often not marked as serializable and binding them to data bound controls may cause exceptions.

This problem can be solved using DTOs. We can create DTOs as flat objects that are serializable. They doesn't contain any child objects - only properties with their values. We can wrap source data to DTOs and bind list of these DTOs to our data bound controls.

Search criteria DTOs

In one of our current project we are using some DTOs to define search criterias. These DTOs are also flat ones because they store only ID-s of search conditions, string tokens and dates. There is one main search DTO and some internal search DTOs. This far we are happy with this solution because if we design those DTOs carefully they are very easy and convenient to use in client code.

Search sitemap DTOs

ASP.NET Futures has support for search engine sitemaps (follow this reference to take a look at the code examples). To let it create a search engine sitemap for products you must define class for products that has specific attributes required by sitemap generating system. This object is also simple DTO because it has no complex attributes.

I am sure that there are many more DTOs, these three were just examples of some additional DTOs besides DTOs we are using with web services. Okay, and as a last word - DTO is design pattern refered also to as Value Object in Sun.

http://weblogs.asp.net/gunnarpeipman/archive/2008/07/18/dto-not-only-for-web-services.aspx

allowDefinition='MachineToApplication' hatası

Bu "MachineToApplication" hatasının sebebini biliyorum.

Eğer uygulaman bir virtual directory içinde değil ise, (sitenin kök dizininde değilde alt klasörlerden birindeyse) herhangi bir dosyaya yapılan istekte, sunucu web.config dosyasını kök dizinde arar. Eğer orada bulamazsa bu sefer machine.config idi sanırım ismi oraya bakar oradaki yapılandırma bir web uygulaması yapılandırmasıyla uyuşmadığı için bu hata meydana gelir.

* Attığın dosyalar sitenin kök dizininde değil alt klasöründe mi?
* Eğer öyle ise, o alt klasörü "virtual directory" olarak tanmlamalısın ve uygulamayı çağırırken o virtual directory nin ismiyle çağırmalısın.

Stopping ASP.NET web.config inheritance

If you are only ever running one ASP.NET application on a website this is not an issue. However, if you are running a site which may have an application at the root and other separate applications running in sub or virtual directories, then Settings inheritance could be a problem.

You can read more about how config files get inherited on msdn but here's a tip for stopping settings in the root app from getting inherited. The tag is the only tag I've come across which has the inheritInChildApplications attribute. So to target the main just wrap it in the location tag as seen below.



...



Other Notes:
Although I think the inheritance is in general a good feature to have, especially for inheriting down things such as security settings. It can even support locking certain settings for child applications, but things can be problematic if the child application doesn't share the same libraries, modules, handlers, masterpages or themes.

Most collections in the web.config have the tag or tag to remove irrelevant modules or handlers in the child app. The problems I've found occur with settings relating to the tag, which most items in it don't support . This means if your child applications doesn't share or have the same registered controls, masterpages or themes then you are probably going to have issues or be forced to specify the settings on a per-page basis. This is where the inheritInChildApplications="false" really comes in handy.



http://dotnetslackers.com/Security/re-55457_Stopping_ASP_NET_web_config_inheritance.aspx

Biggest advantage to using ASP.Net MVC vs web forms

The main advantages of ASP.net MVC are

1) Enables the full control over the rendered HTML.

2) Provides clean separation of concerns(SoC).

3) Enables Test Driven Development (TDD).

4) Easy integration with JavaScript frameworks.

5) Following the design of stateless nature of the web.

6) RESTful urls that enables SEO.

7) No ViewState and PostBack events

The main advantage of ASP.net Web Form are

1) It provides RAD development

2) Easy development model for developers those coming from winform development.

Regarding SoC, people can mess up with it just like they use to on webforms, by writing "fat" controllers with lots of business logic or even data access code in it. So I would say SoC is something that must be provided by the coder, the fw can't help. – rodbv Dec 12 at 15:22

@ rodbv: Very true, but MVC does sort of push you in the right direction, or at least doesn't make you jump through hoops to do so. So maybe that point should read something like 'makes SoC easier to implement' – Erik van Brakel Jan 25 at 23:21


MVC is much easier to test
MVC has better separation of responsibilities
MVC is much easier to create very complex websites with a minimum of code

Web forms are very easy to slap together
Web forms hide away complexity from the developer in web controls
Web forms use the same mental model of development that windows forms use


Biggest single advantage for me would be the clear-cut separation between your Model, View, and Controller layers. It helps promote good design from the start.

Web forms also gain from greater maturity and support from third party control providers like Telerik.

In webforms you could also render almost whole html by hand, except few tags like viewstate, eventvalidation and similar, which can be removed with PageAdapters. Nobody force you to use GridView or some other server side control that has bad html rendering output.

I would say that biggest advantage of MVC is SPEED!

Next is forced separation of concern. But it doesn't forbid you to put whole BL and DAL logic inside Controller/Action! It's just separation of view, which can be done also in webforms (MVP pattern for example). A lot of things that people mentions for mvc can be done in webforms, but with some additional effort.
Main difference is that request comes to controller, not view, and those two layers are separated, not connected via partial class like in webforms (aspx + code behind)

Do you mean development speed or execution speed? – julesjacobs Jan 25 at 23:42
Obviously execution speed. – Andrei Rinea Aug 14 at 11:52

If you're working with other developers, such as PHP or JSP (and i'm guessing rails) - you're going to have a much easier time converting or collaborating on pages because you wont have all this ASP.NET events everywhere.

You don't feel bad about using 'non post-back controls' anymore - and figuring how to smush them into a traditional asp.net environment.

This means that modern (free to use) javascript controls such this or this or this can all be used without that trying to fit a round peg in a square hole feel.

MVC lets you have more than one form on a page, A small feature I know but it is handy!

Also the MVC pattern I feel make the code easier to maintain, esp. when you revisiting it after a few months.

ASP.NET Webforms lets you have as many forms on a page as you want. The limitation is that only one can have "runat="server" attribute. – Andrei Rinea Aug 14 at 11:53

My 2 cents:

ASP.net forms is great for Rapid application Development and adding business value quickly. I still use it for most intranet applications.
MVC is great for Search Engine Optimization as you control the URL and the HTML to a greater extent
MVC generally produces a much leaner page - no viewstate and cleaner HTML = quick loading times
MVC easy to cache portions of the page. -MVC is fun to write :- personal opinion ;-)


http://stackoverflow.com/questions/102558/biggest-advantage-to-using-asp-net-mvc-vs-web-forms

The user instance login flag is not supported on this version of SQL Server. The connection will be closed.

The issue is that User Instancing, which allows the automatic creation of databases from code, isn't support on the full version of SQL 2005. That is a function of SQL Express only. The solution is to manually create the database in SQL Server 2005 and set a connection string to point to it. You will also need to run aspnet_regsql.exe manually against the database if you will be using any of the new built-in database features of ASP.NET v2.0.

http://forums.asp.net/t/913172.aspx

search this blog (most likely not here)