Never worry about ASP. NET Ajax's. d again

Source: Internet
Author: User
Tags hasownproperty
ArticleDirectory
    • ". D" what?
    • Determining whether or not the ". D" is there
    • Don't make me think
    • Datatype: none of your business
    • Wait, isn' t eval () Supposed To Be edevil?
Never worry about ASP. NET Ajax's. d again

Ajax, ASP. NET, JavaScript, jquery ByDave wardOn Jun 29th, 2009

When I recently received this message from a frustrated reader:

After Hours and hours of slamming my head into the desk it turns out it was the darn "D" in the response. my home computer is on. NET 2.0 and my work computer is on 3.5.Jimminie Christmas!

I realized that the ". d "introduced in ASP. net Ajax 3.5's JSON responses is still all too common a stumbling block when calling ASP. net Ajax services through a library such as jquery. in fact, with jquery's popularity among ASP. NET developers on the rise, this appears to haveBecome an even more frequent problem.

Since a lot of people are having trouble with it, I want to share one method you can use to completely isolate your code from the problem. if you bake this into an $. ajax () code snippet or otherwise use it as a template for calling ASP. net Ajax services in jquery, you shoshould never have to think or worry about the ". d "again.

In this post, I will show youHow to detect the ". D"And how you canCompletely isolate your $. Ajax success handler from it.

 

". D" what?

If you aren't familiar with the ". d "I'm referring to, it is simply a security feature that Microsoft added in ASP. net 3.5's version of ASP. net Ajax. by encapsulating the JSON response within a parent object, the framework helps protect against a participant ly nasty XSS vulnerability.

Before ASP. NET 3.5, "scriptservices" and page Methods returned their data at the top level of the JSON response, like this:

In ASP. NET 3.5 and later, the same server-side code returns this:

For more information about the change andWhyThe change is a good one, be sure to see my earlier post: A breaking change between versions of ASP. NET Ajax.

However, what my previous post lacks is a solution for mitigating the inconsistency entirely. Using different client-side code against 2.0 and 3.5 based services is workable, but far from ideal.Wouldn't it be nicer to not have to worry about it?

Determining whether or not the ". D" is there

In order to isolate ourselves from the ". D ", we first need a reliable way to test for its presence. though JavaScript provides several methods for determining this, I suggest hasownproperty, as recommended by Douglas crockford.

By using hasownproperty, your code is protected against unexpected changes to an object's prototype chain. though it is an unlikely problem to encounter, it's always best to code defensively in JavaScript. the browser is a hostile environment!

Using hasownproperty to test for ". D", you might end up with something like this:

$.Ajax  (  { Type :   "Post"  , URL :   "WebService. asmx/methodname"  , Data :   "{}"  , Contenttype :   "App/JSON; charset = UTF-8"  , Datatype:  "JSON"  , Success :   Function  ( MSG )   {      If   ( MSG. Hasownproperty  (  "D"  )  )       // Leave the. d behind and pass the rest        // The JSON object forward. Dosomething ( MSG. D  )  ;      Else        // No. D; no transformation necessary. Dosomething ( MSG )  ;    }  } )  ;  Function Dosomething ( MSG )   {    // Do something with the response data here.    // Keep CT it to consistently have no. D.  } 

This CodeWillPerform identically against any version of ASP. NET Ajax.

Unfortunately, this might still get in your way. you may not always want to use the response in a call to another function, and you'll have to remember the conditional every time you write a success handler.

Don't make me think

I prefer a solution that doesn' t touch the success handler at all. then, you're free to integrate the ". d "handling into a generic $. ajax code snippet in Visual Studio and/or easily copy-paste it between files without modification.

Luckily, jquery provides a mechanisms that allows us to do just that:Datafilter.

The datafilter parameter to $. Ajax allows you to arbitrarily transform a responseJust beforeThe success handler fires. specifically tailored to this sort of situation, it passes response data into a callback function, captures the return value of that callback, and then passes the modified data into your success handler.

Hence, you can forever stop worrying about that pesky ". D" like this:

$. Ajax  (  { Type :   "Post"  , URL :   "WebService. asmx/methodname"  , Data :   "{}"  , Contenttype :   "App/JSON; charset = UTF-8" , Datafilter :   Function  ( Data )   {      // This boils the response string down      // Into a proper JavaScript Object ().      VaR MSG =   Eval  (  '('   + Data+   ')'  )  ;  // If the response has a ". d" top-level property,      // Return what's below that instead.      If   ( MSG. Hasownproperty  (  'D'  )  )        Return MSG.D  ;      Else        Return MSG ;    }  , Success :   Function  ( MSG )   {      // This will now output the same thing      // Upload SS any current version of. net. Console. Log  ( MSG. Foo  )  ;    }  }  )  ; 

Now, regardless which of these JSON forms the server returns:

// ASP. NET 2.0 with the ASP. NET Ajax extensions installed.{'Foo':'Bar'} // ASP. NET 3.5 and 4.0.{'D':{'Foo':'Bar'}}

Your success handler will simply receive this consistent JSON object every time:

{'Foo':'Bar'}
Datatype: none of your business

It's important to note the removal of the datatype parameter in the $. ajax () code above. this is required in order to prevent a double-eval of service responses containing only a single string.

Internally, jquery uses a combination of the datatype parameter and the implicit type the response. if the datatype is "JSON" and typeof (response) is "string", then jquery uses eval () to deserialize the response.

In the example above, manually deserializing the response in datafilter results in it being of type object, jquery leaves it alone, and our datafilter 'd object makes its way back to the success callback either way.

However, if the datatype is set to "JSON" and the ". d "sanitized response happens to be of JavaScript type" string ", jquery will assume that it is a JSON response from the server and still needs to be deserialized. that will throw an error at best.

The solution is to simply drop the datatype parameter from the $. ajax () call. it is only needed for purposes of instructing jquery how to deserialize the response, and we're handling that ourselves now.

Thanks to Brett for pointing this out.

Wait, isn' t eval () Supposed To Be edevil?

If the eval () usage gives you pause, don't worry. for now (as of jquery 1.3.2), this is the same mechanic that jquery uses to deserialize JSON too. though eval ()IsPotentially edevil,It is still a necessary edevil in internal browsers.

In my next post, I'll show you how to modify this to leverage a native browser Implementation of JSON. parse instead of eval (), available in some newer browsers.

Reprinted from: http://encosia.com/never-worry-about-asp-net-ajaxs-d-again/

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.