How can I use jQuery Ajax and PageMethods with instance variables? - asp.net

One reason we currently use UpdatePanels for doing our AJAX is because our BL and DA layers pass around the Page.User.Identity for authentication.
Is there a way to access this?

Yes, you can get the current user via HttpContext.Current.User. From the MSDN documentation for Page.User:
This property uses the HttpContext
object's User property to determine
where the request originates.
As for your broader question, "How can I use jQuery Ajax and PageMethods with instance variables?" The answer is "not directly."
No instance of your page is created when executing a page method. (Why do ASP.NET AJAX page methods have to be static? is a great conceptual overview of the differences between normal page operations and static page methods).
The only way to access instance variables in page methods is to first put the variables into Session during the initial page request - but this is a rather fragile strategy: you're better off figuring out another way to get the data or values in question.

I agree with Jeff Sternal's answer to this post. On my current project, we frequently use the session as a "scratch pad" to store data for later use by PageMethods and ASMX webservices.
However, if you don't like using session in that fashion, here is another approach that should be a viable alternative:
At page-creation time, you can put instance variable values into javascript vars or hidden fields. From there, they can easily be accessed by javascript/jquery and included as params on calls to webservices. You could then code your webservices (PageMethods, ASMX services or others) to take those values as parameters.

Related

Organizing Master-Detail Controllers ASP.Net Web API

I am trying to determine the best way to implement the retrieval of detail records based upon the master's ID.
Obviously you would set up API controllers for both master and detail.
Solutions I've considered:
Have API consumers use OData to get all details filtered by a master ID. While I don't have an issue with this solution, I kinda feel bad putting that onto the API consumer and feel it is something that should be handled internally by the API
Go against the convention of just having the Get/Put/Post/Delete methods and create an action of "GetMastersDetails" on the detail controller and make it accessible via routing. While this would certainly work, I feel this gets away from the whole point of Web API (to an extent).
Create a 3rd controller named "MastersDetailsController" which would have a Get based upon a master ID with different possible return types:
Which would return a list of detail IDs which would then be used to call a Get on the details controller to get those actual details
Which would return a list of actual detail objects. What I don't like about that is having a controller returning a different type than what it is based upon.
Option 2 will be fine. Option 1 opens up a lot more risk depending on your scenario, and what you want to allow the user to get at.
It's not really "against convention" to add custom methods to an ApiController. You can do that however you like. It would only be "against convention" if you did so and used the wrong HTTP methods (i.e. a GET when you're deleting something in your custom method).
I'd go with either #1 or #2.
For #1, OData support enables not only the scenario you describe but offers a lot of additional functionality which might be desired in the future.
For #2, I don't think it gets away from the point of Web API's. Maybe a bit from a true RESTful service, but it's easy to implement and easy to understand.

High level overview of ASP.net

I've spent a lot of time working in Django, and have grokked the framework well enough that I have started replacing the original components (view engine, etc.) with my own custom components and the sky hasn't fallen down.
I've been looking at ASP.NET MVC, and been quite interested (I really like C#/F#) but so far have learned... just about nothing. I've been digging through http://www.asp.net/mvc/mvc4 without much success. I suppose my main questions would be:
What are the main moving parts in a typical workflow? Let's say a request comes in. Who takes it, does stuff, and passes it on to who else? In Django, for example, a request goes through the URL Mapper, Middleware, goes to a controller, which may dig through some models (via explicit function calls) and get some data, pass it into a template (also via an explicit function call) to be rendered and pass it back.
What kind of client-server coupling is there? For example, in many frameworks there is a explicit coupling of each HTML-form with a serverside-validator, with a model, with a database table, such that client side validation code is automatically generated. Another example is Quora's Livenode, which explicitly links client-side HTML components with their dependencies in the model, allowing changes in the database to propagate and automagically update client-side code.
I think there is no better answer to your first question than ASP.NET MVC Pipeline :
http://www.simple-talk.com/content/file.ashx?file=6068
explained in more detail here :
http://www.simple-talk.com/dotnet/.net-framework/an-introduction-to-asp.net-mvc-extensibility/
To your second question : answer is none. ASP.NET application dont even have to render HTML output, you can write your own viewengine to give any representation of the data, not consumed by browser, but any http (REST) capable device. The only things you can consider as coupling "conventions" (for model binding for example), but they can be replaced and extended in any way you like.
What kind of client-server coupling is there?
As rouen said, none.
I am not familiar with Django, but unlike other MVC frameworks (including Rails) ASP.NET MVC is very skinny in that it only implements Views and Controllers of the traditional MVC pattern. You are pretty much on your own for the model part. That means there is no built-in support for database creation, ORM, et cetera.
ASP.NET MVC does implement a bunch of plumbing to route requests to the appropriate controllers and even some binding of parameters (e.g. query string parameters, form values) when instantiating controllers but this binding is not to a full blown model. The binding in this context is usually either single values or "viewModels"
ASP.NET MVC also implements the plumbing to select the right view to render.

Google Geocoding Recommendation

I am looking into utilizing Google Maps API to do some geocoding. I want to implement client side geocoding, to remove the possibility of request limitation.
I need to do some fairly complex logic on the result set, and I would prefer to do that in C# as it is a ASP.NET MVC application. However part of that logic is possibly makeing subsequent follow up requests and that again would require JavaScript.
So, my first thought is to make a service in my application to pass JSON results to and certain return types to trigger the subsequent request. That seems a little convoluted and want to know from the community if this seems like the best approach and if there are any libraries/third party tools that can help handle this situation.
I've an app that does something similar, with the complexity somewhat decoupled by using standardized events (within this app, not a W3 standard or anything)
Client uses native geolocation, SimpleGeo and Google Loader to guess where the user is and AJAX's that to the server.
Server uses client data, MaxMind, and user preferences to decide where to treat the user as being.
Server response is generic event data (as JSON response) that is converted by a generic AJAX response handler into one or more events triggered against the body element.
Depending on the page, various listeners are bound to the events and or namespaces (see jQuery namespaced events) and they handle the updated location events, e.g., getting different weather data, changing local search results
Some of those listeners in turn trigger other AJAX requests, the responses to those may also carry generic events to triggered...
This way there's no sequential code I have to write, i.e., I can add or remove behaviors (simple or complex) without changing anything else. jQuery Events are all I use, really nothing much to it after you decide how you'll pattern things.
Let me know if that's interesting to you and you want me to expand or clarify a part of it.
You may want to try this API:
http://code.google.com/apis/maps/documentation/geocoding/
It's far more REST like - no Javascript required. May work better with C#
In the end I found the best solution was to do as I stated in my question. Pass the JSON object to controller, do work, then return. Worked pretty well.

ASP.NET MVC 2 - best implementation of status / update / generic message delivery and JavaScript modal display

For an MVC 2 app that relies on many partial views and almost exclusively uses Ajax for POSTs/GETs, what would be the best way to implement the setting, passing, retrieval and display (using a JavaScript modal) of these messages?
My forms all POST (by way of jQuery $.ajax) to actions that return partial views (html) that are used to update a in the "success:" part of the $.ajax function.
I was hoping for some sort of mechanism in the master view that could "listen" for any messages that any of these partial views might be "delivering"--through their ViewData, for instance.
Thanks.
Edit:
After lots more searching, I found similar people trying to achieve the same thing as me, but none of the questions had a good answer. This one states the question best.
Your "master view" wouldn't be able to have a mechanism like what you're thinking of simply because you're asking it to be aware of potential data that could be given to it based on a possible user interaction.
What I think #cottsak is trying to say is to have delegate functions in your JS code that handle error and success events. Thus you can have 100 Ajax requests but only 2 functions actually handling the response. Within these functions you'll have to normalize the way you deal with the responses so that you don't have to write conditionals for specific forms for example. This might require normalizing your forms to have identical structures and base functionality and differ only on their input content.
For example I use "Wizards" in some of my sites that deal with modal forms:
<div class="Wizard">
<form>
<!-- Any and all possible content -->
</form>
</div>
All my forms of course differ on the actual inputs they have, but they're all normalized in the sense that there's dedicated elements in them for messaging and such. Every single form however is controlled by the same JS with a few exceptions for special scenarios.
You should take a look at the Dropbox web interface. Get yourself a free account and use the interface for 10 mins - copy, move, delete a file. The messaging and validation system is great. And it's largely ajax on their site too. Perfect example of the user experience you want it sounds like.
As for the technical implementation, i have been thinking about this for some time:
I'd use a broker system on the client for which all page ajax requests go through. This way all responses can be collated within a single function (/object, however you design it) and thus the responses too. It's obviously the responses that are key so that Error messages and Status messages can be handled in the same place and rendered to the user in a uniform way.
Server side it wouldn't be too hard. I'd suggest that you have a graceful degradation solution to those actions that return JSON or other ajax responses, in that they can function (and return Error/Status messages) without the client having JavaScript enabled.

How do I mock/fake the session object in ASP.Net Web forms?

Is there a way to mock/fake the session object in ASP.Net Web forms when creating unit tests?
I am currently storing user details in a session variable which is accessed by my business logic.
When testing my business logic in isolation, the session is not available. This seems to indicate a bad design (though I'm not sure). Should the business logic layer be accessing session variables in the first place?
If so, then how would I go about swapping the user details with a fake object for testing?
You can do it with essentially 4 lines of code. Although this doesn't speak to the previous comment of moving session out of your business logic layer, sometimes you might need to do this anyway if you're working with legacy code that is heavily coupled to the session (my scenario).
The namespaces:
using System.Web;
using System.IO;
using System.Web.Hosting;
using System.Web.SessionState;
The code:
HttpWorkerRequest _wr = new SimpleWorkerRequest(
"/dummyWorkerRequest", #"c:\inetpub\wwwroot\dummy",
"default.aspx", null, new StringWriter());
HttpContext.Current = new HttpContext(_wr);
var sessionContainer = new HttpSessionStateContainer(
"id", new SessionStateItemCollection(),
new HttpStaticObjectsCollection(), 10, true,
HttpCookieMode.AutoDetect, SessionStateMode.InProc, false);
SessionStateUtility.AddHttpSessionStateToContext(
HttpContext.Current, sessionContainer);
You can then refer to the session without getting a NullReferenceException error:
HttpContext.Current.Session.Add("mySessionKey", 1);
This is a combination of code I compiled from the articles below:
Unit testing with HttpContext
Faking a current HttpContext
SimpleWorkerRequest, HttpContext, and session state
Unit testing code that uses HttpContext.Current.Session
In ASP.NET, you can't create a Test Double of HttpSessionState because it is sealed. Yes, this is bad design on the part of the original designers of ASP.NET, but there's not a lot to do about it.
This is one of many reasons why TDD'ers and other SOLID practictioners have largely abandonded ASP.NET in favor of ASP.NET MVC and other, more testable frameworks. In ASP.NET MVC, the HTTP session is modelled by the abstract HttpSessionStateBase class.
You could take a similar approach and let your objects work on an abstract session, and then wrap the real HttpSessionState class when you are running in the ASP.NET environment. Depending on circumstances, you may even be able to reuse the types from System.Web.Abstractions, but if not, you can define your own.
In any case, your business logic is your Domain Model and it should be modeled independently of any particular run-time technology, so I would say that it shouldn't be accessing the session object in the first place.
If you absolutely need to use Test Doubles for unit tets involving HttpSessionState, this is still possible with certain invasive dynamic mocks, such as TypeMock or Moles, althought these carry plenty of disadvantages as well (see this comparison of dynamic mocks).
Your instincts are correct---you shouldn't be accessing pieces of the ASP.NET framework from your business logic. This would include Session.
To answer your first question, you can mock static classes using a product like Typemock Isolator, but you'll be better off if you refactor your code to wrap access to Session in an interface (i.e., IHttpSession.) You can then mock IHttpSession.
In Asp.Net webforms, you cannot escape the fact that framework's entry into your code comes from aspx pages. I agree that your business layer should not touch the asp.net specific components directly but you have to have a model's storage container and session in asp.net is a good area. Thus, one possible approach is to create ISessionManager for purpose of interacting inside your business layer. Then, implement the concrete type by using HttpSessionState ... btw, a good trick is to use HttpContext.Current.Session to implement accessors/getters out of the HttpSessionState.
Your next challenge would be how to wire it all together.
One approach is to pass a lambda expression to your code that takes a string (or some other object) as input, and uses it to set either the Session object or a test container.
However, as others have said, it's a good idea to move access to the Session object out of your BLL.

Resources