I'm rewriting some old application, written in ASP.NET MVC. It used authentication by LDAP, but now it is necessary to rewrite it to OAuth2. I've decided to use DotNetOpenAuth library as it looked like best choice, but I'm stuck on auth response.
Currently, I have one controller class called AccountController, containing some methods, but most important are RedirectToIS and PostAuth (which is an redirect uri):
public ActionResult RedirectToIS()
{
DotNetOpenAuth.OAuth2.AuthorizationServerDescription asd = new DotNetOpenAuth.OAuth2.AuthorizationServerDescription();
String site = ConfigurationManager.AppSettings["oauth:site"];
asd.AuthorizationEndpoint = new Uri(site + "/oauth/authorize");
asd.TokenEndpoint = new Uri(site + "/oaut/token");
asd.ProtocolVersion = DotNetOpenAuth.OAuth2.ProtocolVersion.V20;
this.oaclient = new DotNetOpenAuth.OAuth2.WebServerClient(asd, ConfigurationManager.AppSettings["oauth:appid"], ConfigurationManager.AppSettings["oauth:secret"]);
this.oaclient.RequestUserAuthorization(null, new Uri("http://localhost/Account/PostAuth"));
return View();
}
The PostAuth method is what I am trying to make to work correctly. It is page, where the OAuth2 server redirect user after successful authorization with code and state GET parameters. Because I'm trying to utilize library and not (re)write it, I've stuck here - I don't know what to do now.
I tried, as I've seen in one example, use DotNetOpenAuth.OAuth2.IAuthorizationState st = this.oaclient.ProcessUserAuthorization(); in PostAuth, but it don't work. In example author had original WebServerClient instance, but I can't achieve it with Session nor using AccountControler data item.
So, finally, my question: How to transfer object oaclient from RedirectToIS method to PostAuth method (some kind of session?) or how to start using OAuth?
PS: I'm not new to C#, but I've never used ASP.NET.
Related
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.
I'm not sure of the best way to accomplish my goal. Looking for insight. I'm familiar with WebAPI services consumed through WPF and Silverlight but this is my first run at ASP and MVC.
I am building a site to verify contents of a shipment against an electronic manifest (EDI 856). I have a page that displays the shipping data and I need the users to scan each item barcode in the container. I would then like to pass that barcode to a service, verify the item belongs in that shipment and then update the page to show as much.
My plan was to have a single text box into which the user could scan/type the barcode and then submit that data to a WebAPI service which would verify the information and then probably use SignalR to send a message back to the page and update a grid with the item data.
If this is a decent way to go, I'm just not quite sure how to use ajax to call the WebAPI endpoint and provide the data I need.
I would advise against using SignalR in this situtation. What you need, judging from your description, is the most basic use case of submitting an ajax request and receiving a response.
You are not designing a system where you need the server to initiate communication with the browser or anything like that, where sockets (and SignalR as an abstraction over sockets with fallbacks to less suitable protocols) is a huge overkill.
Don't worry, your use case is rather simple.
It's a little out of scope to describe how to setup a WebApi project, how to configure routing, action names, etc. Simple google searches will surely provide ample quality tutorials on getting started.
I'll just try to explain what the general idea is, with some code samples, to get you thinking in the right direction.
You need to create an ApiController.
The simplest version of that Controller will probably look something like this:
public class ShipmentVerificationController : ApiController
{
//this is the response object you will be sending back to the client website
public class VerificationResult
{
public bool Valid;
}
public VerificationResult GetIsItemValid(string BarCode)
{
bool itemIsValid;
// Implement checks against the BarCode string here
itemIsValid = true;
return new VerificationResult { Valid = itemIsValid };
}
}
Note that the inner class represents the response you will be sending back. It should be properly filled out with additional info if needed and probably put into a separate .cs file in the "Models" folder or where ever you see fit.
I have declared it inside the controller for demonstration purposes only
Once you have a WebApi service deployed, it's really easy to send it data from your website and receive the feedback.
To simplify Ajax requests, jQuery is often used.
Once the user inputs the barcode into a textbox, you can hook up an event to check for return key being pressed (most barcode scanners send the return key command after they input the barcode data) and then write something along the lines of:
var barcode = $("#input-field").val();
$.getJSON( "<url_to_your_webapi_service>/api/ShipmentVerification/GetIsItemValid/" + barcode, function( data ) {
if (data.Valid) {
// great, highlight the item as valid
}
else {
//better indicate an error with the scanned item
}
});
Please note that for simplicity I have not included any error handling, url parameter encoding, and most importantly, zero authorization.
Authorization is very important if you deploy the web service to the open web but still do not want anyone to be able to call it.
You will have to research these topics yourself, but I hope I have presented you the core concepts and logic behind a simple service such as this, so you have a base to start with.
If you come up with specific problems and questions post a new question.
I actually found a more simple way to do this. I nixed the idea of using a WebAPI endpoint and just went with a normal controller. I used ajax to prevent the page from refreshing with the new view, since that view is actually just json data with my return values in it.
I am try to integrate SagePayMvc.dll into a ASP.NET Web API project which requires ControllerContext.RequestContext to be passed in order to form the Notification Url.
Currently I am experiencing some difficulties in achieving this, I need to pass the ControllerContext.RequestContext from this web api controller:
public class PaymentStartController : ApiController
{
private PaymentRepository paymentRepository = new PaymentRepository();
private SagePayHelper sagePayHelper = new SagePayHelper();
public Order MakePaymentInitial(Payment payment)
{
Order order = new Order();
order = sagePayHelper.MakePayment(payment, context);
paymentRepository.InsertVendorTXCode(order.VendorTxCode);
paymentRepository.InsertInitialPaymentDetails(order, payment);
return order;
}
}
I have tried to add a public ControllerContext controllerContext = new ControllerContext() below the SagePayHelper instantiation and then subsequently added var context = controllerContext.RequestContext, the problem with this none of the methods inside RequestContext are instantiated either so when SagePayMvc arrives at the point of building the Notification Url which is done inside an IUrlResolver interface an error is thrown.
Is there a way of mocking up ControllerContext.RequestContext, I have previously used RhinoMocks or would it be more prudent to revert to the way I previously implemented SagePayMvc down in the forms project (the forms project is an MVC 4 application that serializes and sends the form data to the web api).
Any advise would be much appreciated.
ASP.NET Web API uses completely different runtime components from ASP.NET MVC for representing the context and request/response messages. It looks like the API you are using is heavily tied to ASP.NET MVC, which makes it really hard to reuse in ASP.NET Web API unless you initialize the ASP.NET MVC content doing manual mappings. I think it would be easier for you to just use ASP.NET MVC for invoking that method expecting the MVC context.
I have been struggling on trying to work this for the last 3 days, how do you pass data from an api controller into an mvc controller and use the data to populate a selectlistitem.
I have seen plenty of examples of calling the api from the webpage which is all well and good, but what if the user has javascript disabled, it will not display the data.
So any help with an example for this would be much appreciated.
My code is:
web.api
public IEnumerable<DisplayCurrencyInDDL> GetCurrencyForDDL()
{
var s = _ICurr.InsetCurrencyIntoDataBase();
return s.AsEnumerable();
}
mvc controller
WebClient wc = new WebClient();
var s = wc.DownloadString("http://localhost:50687/api/Currency");
How do I get the value from var s (currency and currencyid) into a selectlistitem.
Thanks
George
edit data returned as: [ { "strCountry": "Afghan Afghani", "strCountryCode": "AFN" }, { "strCountry": "Albanian Lek", "strCountryCode": "ALL" }, { "strCountry": "Algerian Dinar", "strCountryCode": "DZD" }, { "strCountry": "Andorra Euro1",
I don't understand why you are doing it this way.
If you want to share some code you can do this by moving the code into
some Library and instantiate that class in WebAPI and also in your MVC
Controller.
Ok, so after reading this post on stackoverflow difference between apiController and controller
Its my understanding that if i'm returning data to my own website, then use mvc controller, but if i'm allowing a 3rd party to consume data from my site, then put the data in an api controller.
Also if a user visited my site/your site and had javascript disabled, then json would not work on the client side as requires jQuery etc, so my understanding is use api if you are sure the visitor will not have javascript disabled.
Please let me know if that correct
I've made a little game in silverlight that records users scores whilst they play.
I decided it would be a lot better if I could implement a leaderboard, so I created a database in mySQL to store all the high scores along with names and dates. I have created some communications to the database in ASP.net. This works and I can simply insert and get data within the code.
It's now time to link the silverlight project with the ASP.net database communications, so I can send the users name and score as variables to my ASP.net code and then it will upload it to the database. That's all I need. Surely there must be an easy way of doing this, I just can't seem to find any ways when researching.
Thanks in advance,
Lloyd
At first you need add Generic Handler to your ASP.Net project.
public class Handler1 : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string userName = context.Request["user"];
int score = int.Parse(context.Request["score"]);
//And store it in DB
}
}
After you need call this handler from SilverLight app:
string uri = HtmlPage.Document.DocumentUri.ToString();
// Remove the web page from the current URI to get the root URI.
string rootUri = uri.Remove(uri.LastIndexOf('/'),
uri.Length - uri.LastIndexOf('/'));
string diggUrl = String.Format(rootUri + "/" + "test.ashx?user={0}&score={1}", "testuser", "234");
// Initiate Async Network call to Digg
WebClient diggService = new WebClient();
diggService.DownloadStringAsync(new Uri(diggUrl));
here i used Uri Class to send parameter to asp.net, but you can send string format only.
// this code written on Silverlight Button Click Event.
Uri myURI = new Uri(HtmlPage.Document.DocumentUri,String.Format("Report.aspx?brcd={0}&acc={1}&user={2}", Brcd, Acc, User)); HtmlPage.Window.Navigate(myURI, "_blank");
below code is written on Asp.net page_load or page init event
Brcd = Request.QueryString["brcd"];// brcd value accept here.
acc= Request.QueryString["ACC"];`
user= Request.QueryString["User"];
in above code we accept the silverlight parameter in asp.net but in [] bracket put name as it is use in silverlight page because it case sensitive.
By ASP.NET, do you mean an ASP.NET Webforms app?
If so, an ASP.NET Webforms app is a method of building a UI. What you need is an API, for your Silverlight app to use programatically. For this purpose you may want to consider building an ASP.NET Webservice instead, which provides an API over HTTP.
What do you need its to send data to web server from a Silverlight application, right?
You can:
Call Javascript functions from Silverlight and, there, do a postback
Call web services with Silverlight, but make sure its in same server which your SL application came from, or you will face some XSS issues.
An easy way to do this is to have your Silverlight code create a REST URL by encoding the information into the query string, and invoking an .aspx page on the server. The page wouldn't need to return any markup; it would just handle the back-end stuff and return.
Alternatively, you could make a web service call from Silverlight to your back end.
I prefer the latter approach. It's a little more work the first time through, but it's also more general purpose and makes for generally better code in the long run.
Although technically you could use JavaScript, I wouldn't suggest it; why go backwards in tech if you don't have to?