How to get data from another page - c#

The functionality exists in pageB.aspx and the parameters are passed from pageA. I'm failing to get the result of pageB. What should be done here.
pageA.aspx.cs:
string URI = Server.MapPath("~/pageB.aspx");
NameValueCollection UrlParams = new NameValueCollection();
UrlParams.Add("section", "10");
UrlParams.Add("position", "20");
using (WebClient client = new WebClient())
{
byte[] responsebytes = client.UploadValues(URI, "POST", UrlParams);
string responsebody = Encoding.UTF8.GetString(responsebytes);
}
when the compiler reads byte[], there is a dialog which asks if changes should be made to pageB. On clicking No, nothing happens. The string 'responsebody' is empty.
pageB.aspx.cs::
protected void Page_Load(object sender, EventArgs e)
{
if (int.TryParse(Request.QueryString["section"], out section)
&& int.TryParse(Request.QueryString["position"], out position))
{
ProcessData();
}
}
private string ProcessData()
{
string HTMLContent = string.Empty;
try
{
//some code to render the string.
return HTMLContent;
}
catch (Exception ex)
{
throw ex;
}
}
I would like to get 'HTMLContent' from pageB

Use HttpContext.Current.Request["Key"] instead of Request.QueryString["Key"].
if (int.TryParse(HttpContext.Current.Request["section"], out section)
&& int.TryParse(HttpContext.Current.Request["position"], out position))
{
ProcessData();
}

Having pageA 'load' PageB via a web request is probably not the best idea in the world.
My reasoning for this is that I have seen it done on various projects and you can run into all sorts of problems with the routing of the request and permissions.
Essentially the PageA->PageB request will be treated like a new user loading PageB, cookies, session variables etc will be lost unless you explicitly populate them. firewall rules, routing, load balancing etc will act in odd ways.
Any of these problems could cause your unexpected behavior of PageA
Instead : Move the functionality out of pageB into a service object and call it directly from where needed.
However : Say for some reason you are required to do it via a web request. Perhaps its not always on the same server or something.
It looks from your sample code like you are treating PageB as a webservice. You pass in the parameters and use the whole response. So you could if required expose the underling code, lets call it ServiceB as a WebServiceB and then reference it from PageA via the web request.
This would be 'allowed' as the encapsulation of the data as a WebSerivce make it obvious that PageB is not a page of itself and should not rely on variables such as session, cookies etc which are not explicitly passed in.
Further more the calling code, 'knows' that the webservice could be on any machine in the world and thus won't expect it to know about things unless they are explicitly passed.
If you do change PageB to a service and you still need a stand alone PageB which returns HTML. Simply make a new PageB which calls ServiceB behind the scenes. This allows you to separate your 'view' logic from the data/logic provided by the service

Try using Session if you want to pass any type of data between different pages.
EDIT :
Since Session wont be working in your case, you could also try using WebCache instance to store information and access it across other pages.
This link might help here : MSDN : WebCache
Hope this helps.

Related

HttpClient .Result hangs when [WebMethod] attribute used

First i think i need to declare im a C# novice. I'm a JS and CSS dev with a fair bit of C so this is relatively new territory.
So what i have is an ASP.NET page where i'm making an AJAX request to the code behind, this is then making a request to a WebAPI service to download a zip file to the code-behind, the client does not need to receive the zip.
When i stick the code below into the Page_Load it all works fine and i get a byte array of the zip file. However when used in the method with [webmethod] attribute it hits the webAPI service but hangs. When the service returns nothing happens.
It locks up on line var res = client.GetAsync("/someURl").Result.
I have control over the WebAPI but as its returning fine and everything works fine when the attribute is not used i don't believe the issue is on that end. However i can post related code from there too if needed.
So i have two questions, firstly what on earth could be going on cause this behavior?
Second i've got a good handle on garbage collection is JS when working with closures etc but not here. Ive heard conflicting advice that i should and shouldn't use the using keyword on the HttpClient object. I'm not using a single client object throughout but creating a new one every time the ajax method is hit. So having using is right here isn't it?
EDIT:
The delegate handler is adding some headers to the request to deal with authentication that's all.
[WebMethod]
public static bool SyncApplicant(int id)
{
var serviceOne = DIFactory.Resolve<IServiceOne>();
var settings= serviceOne .GetCompanySettings();
try
{
var delegatingHandler = new WebApiDelegatingHandler((Guid)settings.AppId, settings.ApiKey);
using (var client = HttpClientFactory.Create(delegatingHandler))
{
client.BaseAddress = new Uri(settings.ApiUrl);
using (var res = client.GetAsync("/someURl").Result)
{
var d = res.Content.ReadAsByteArrayAsync().Result;
}
}
}
catch (Exception ex)
{
var x = ex;
return false;
}
return true;
}
Thanks for any advice.
Most probably, that deadlock is being cause by the ASP.NET synchronisation context (see details here].
You can try using ConfigureAwait(false); on the async call to avoid the async continuation trying to acquire the synchronisation context.
I don't know how you would use AJAX to let a user download a file in a browser. You can use a standard HTML link to a new .aspx page and put your Web API-calling code in Page_Load of the new page you're linking to.

Moving data from one web form to another ASP.NET C#

I am trying to move the content of a textbox on the from StudentRegistration to the form MyProfile by following a tutorial on YouTube. However when I try to reference the StudentRegitration Page in my code, I get the error that the type or namespace cannot be found.
In the tutorial I can see that in their code they have a namespace, however my website does not. Could anyone tell me what to do in order to be able to reference StudentRegistration without getting an error?
I should have stated that I have a website not a web app. I have found that websites do not have a default namespace. How would I go about accessing the StudentRegistration without referencing a namespace?
public partial class MyProfile : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (PreviousPage != null)
{
StudentRegistration LastPage = (StudentRegistration)Context.Handler;
lblEmail.Text = StudentRegistration.STextBoxEm;
}
}
}
Rather than answer your question directly, I'd like to point out another issue with your code that will probably prevent it from working. You should refer to the documentation on the PreviousPage property at: http://msdn.microsoft.com/en-us/library/system.web.ui.page.previouspage%28v=vs.110%29.aspx
It does NOT work like this:
user visits /StudentRegistration.aspx
user does stuff
user submits the form on /StudentRegistration.aspx
server redirects the user to /MyProfile.aspx
MyProfile class knows that PreviousPage = the class from /StudentRegistration.aspx
Instead, the description from the msdn reference page linked above stipulates that the PreviousPage property only works on this scenario:
user visits /StudentRegistration.aspx
user does some stuff
user submits form on /StudentRegistration.aspx
server transfers request to the MyProfile class
this does not mean that the url has changed to /MyProfile.aspx for the user, this means that the server is going to treat the current request to /StudentRegistration.aspx as if it were actually a request to /MyProfile.aspx
the user ends up seeing the result of what would normally be /MyProfile.aspx on /StudentRegistration.aspx
Now, your code may actually want that, but the fact that you have:
if (PreviousPage != null)
{
StudentRegistration LastPage = (StudentRegistration)Context.Handler;
// this should be
// StudentRegistration LastPage = (StudentRegistration)PreviousPage;
}
makes me think that you have misinterpreted the somewhat misleadingly named PreviousPage property. For a sample of how to persist state across multiple page loads in .NET, I would recommend reading up on SessionState. It has a somewhat complicated name, but does more of what you would want in this scenario:
http://msdn.microsoft.com/en-us/library/ms178581%28v=vs.100%29.aspx
An added bonus is that you do not need to reference one class from another, so you fix your current bug later on. Additionally, even if you did resolve your potential namespace error, the issue that I outlined earlier will cause the value of the text field to be blank if your code is working as I suspect.
You are sending data from a source to a target - e.g. StudentRegistration -> MyProfile
You have options because at the end of the day, it is HTTP. Aside from "persistence" (Session), and the tutorial you are following, a "simpler" way is to use ButtonPostBackUrl.
All it means is that you are POSTing data to the target page. The target page (MyProfile) will have to validate and parse the posted data (Request.Form). This way you don't have to manage things like Session state.

How can I safely handle POST parameters in an HTTP Handler using C#?

I'm working on an ASP.Net C# application (my first!) that contains an HTTP Handler within it. My application works with several parameters that are passed in via the URL. My question(s) is as follows:
My applications entry point is via the HTTP Handler. When I enter my ProcessRequest method, I am assigning the values of the URL parameters to variables so that I may do something with the data.
Question: Is this safe, even if I am not setting the value to anything when I call the URL?
In my example: I call host/handler1.ashx instead of host/handler1.ashx?something=foo
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
string something = context.Request["something"];
context.Response.Write("Hello World: " + something);
}
When calling the above method using the plain URL with no parameters, it executes just fine, but the string something is just blank/null.
Additional questions:
What happens to the variable something in the case that I do not explicitly initialize it via the URL? I understand that it is null, but can this lead to problems?
Is it dangerous or not safe to call the plain URL (i.e. should I always call it with parameter values specified)?
What is the best way to call a "clean" ashx URL to start the application but not risk problems?
The application will do a series of subsequent GET redirects as it accumulates values and passes them back to the app via the query string.
Should I do a POST or GET upon initial call of the application?
Sorry for asking the same question multiple ways, but I'm a bit confused on the topic and this is my first time writing an app like this. Any patience and advice you could provide on how to safely handle and initialize parameters is greatly appreciated!
There is nothing wrong with omitting parameters to an endpoint. As the developer you are in charge of enforcing what the client is allowed send to you. If you expect a parameter and it's missing, throw an error (e.g. HttpException).
If you are creating or updating data (i.e. inserting or updating records in a database) the best method would be a POST or PUT.
Edit - Here is an example of how you can handle the input:
public void ProcessRequest(HttpContext context) {
//Maybe you require a value?
if (string.IsNullOrEmpty(context.Request["something"])) {
throw new HttpException(400, "You need to send a value!");
}
//Maybe you require a certain value?
if (context.Request["something"] != "beerIsGood") {
throw new HttpException(400, "You need to send the right value!");
}
}
You can't. The Internet is dangerous.

How can I get web service method being called by HttpContext?

I have web service with 40 different web methods.
Can I get in my web service the Method that the request sent from using HttpContext?
I need it because I have abstract general command that all the methods activate and I have access only to HttpContext.
Thanks!
If I understand correct your question you can use PathInfo property of the HttpRequest:
string methodName = HttpContext.Current.Request.PathInfo;
The string methodName will be the method name with the slash prefix (/): "/MyWebMethod".
You probably need:
HttpContext.Current
But be sure you've the ASPX compatibility mode turned on, otherwise you'll not be able to access that property
You can also save the name of the function into the Items array like this:
void myServiceMethod()
{
HttpContext.Current.Items["MethodName"] = "myServiceMethod";
// ...
// here comes your method implementation
}
and then you can anywhere read the HttpContext.Current.Items["MethodName"]
colection HttpContext.Current.Items is valid always only for current request, so you can use it as a storage for any request related information.
When the request is responded, it's garbage.

.Net Form POST

I've got a client that, during testing, is giving me conflicting information. I don't think they are lying but more confused. So, I would like to setup some simple auditing in my ASP.Net application. Specifically, right when any page is called, I want to immediately insert the Querystring and/or form POST data into a log table. Just the raw values.
Querystring is easy. But there doesn't seem to be a way to get the raw form POST'ed data without using BinaryRead, and if I do that, then I screw myself out of using the Request.Form collection later on.
Does anyone know a way around this?
EDIT: tvanfosson suggested Request.Params. I was looking for something that was easier to use (like Request.Querystring, only for POST), but I guess I could just as easily loop through all params and build a string of name=value&, etc).
You can create a custom HttpModule to capture all request made to your application so you don't need to touch every page and you can use it only during testing just not to slow down performance in production.
A sample implementation would be:
public class CustomModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.EndRequest += new EventHandler(context_BeginRequest);
}
private void context_BeginRequest(object sender, EventArgs e)
{
HttpContext context = ((HttpApplication)sender).Context;
// you can use the context.Request here to send it to the database or a log file
}
}
You need to add the module to your web.config
<httpModules>
<add name="CustomModule" type="CustomModule"/>
</httpModules>
All of the form data should be in Request.Params. You'd need to do this on every page, though or maybe use an HttpModule.
[EDIT] If you want to get the form parameters separately use Request.Form, along with Request.QueryString
I would recommend implementing and HttpHandler or an HttpModule for this type of scenario. You can get to the POST Data from the Page_Load event but implementing this logging facility here is not as maintainable.

Categories

Resources