Search Results

Search found 10246 results on 410 pages for 'challenge response'.

Page 58/410 | < Previous Page | 54 55 56 57 58 59 60 61 62 63 64 65  | Next Page >

  • migrating an embedded jetty server from v6 to v7

    - by Ceilingfish
    Hi chaps, I have an embedded servlet which I use in unit tests, looks like this: public class UnitTestWebservices extends AbstractHandler { private Server server; private Map<Route,String> data = new HashMap<Route,String>(); public UnitTestWebservices(int port) throws Exception { server = new Server(port); server.setHandler(this); server.start(); } public void handle(String url, HttpServletRequest request, HttpServletResponse response, int arg3) throws IOException, ServletException { final Route route = Route.valueOf(request.getMethod(), url); final String content = data.get(route); if(content != null) { final ServletOutputStream stream = response.getOutputStream(); stream.print(content); stream.flush(); stream.close(); } else { response.sendError(HttpServletResponse.SC_NOT_FOUND); } } .... } That's written using version 6.1.24 of Jetty. I tried switching over to use Jetty 7.1.1.v20100517, and updated that code to this: public class UnitTestWebservices extends AbstractHandler { private Server server; private Map<Route,String> data = new HashMap<Route,String>(); public UnitTestWebservices(int port) throws Exception { server = new Server(port); server.setHandler(this); server.start(); } public void handle(String url, Request request, HttpServletRequest servletRequest, HttpServletResponse response) throws IOException, ServletException { final Route route = Route.valueOf(request.getMethod(), url); final String content = data.get(route); request.setHandled(true); response.setContentType("application/json"); if(content != null) { response.setStatus(HttpServletResponse.SC_OK); final Writer stream = response.getWriter(); stream.append(content); } else { response.sendError(HttpServletResponse.SC_NOT_FOUND); } } } But whenever I tried to access make a request to the server it would hang indefinitely. Has anyone experienced anything similar?. It also printed this into the log: log4j:WARN No appenders could be found for logger (org.eclipse.jetty.util.log). log4j:WARN Please initialize the log4j system properly. org.eclipse.jetty.server.Server@670655dd STOPPED +-UnitTestWebservices@50ef5502 started

    Read the article

  • PERL script error.

    - by FRESHTER
    !/usr/bin/perl use WWW::Mechanize; use Compress::Zlib; my $mech = WWW::Mechanize-new(); my $username = "9703460016"; #fill in username here my $keyword = "1raja1"; #fill in password here my $mobile = $ARGV[0]; my $text = $ARGV[1]; $deb = 1; print length($text)."\n" if($deb); $text = $text."\n\n\n\n\n" if(length($text) < 135); $mech-get("http://wwwl.way2sms.com/content/index.html"); unless($mech-success()) { exit; } $dest = $mech-response-content; print "Fetching...\n" if($deb); if($mech-response-header("Content-Encoding") eq "gzip") { $dest = Compress::Zlib::memGunzip($dest); $mech-update_html($dest); } $dest =~ s/ $mech-update_html($dest); $mech-form_with_fields(("username","password")); $mech-field("username",$username); $mech-field("password",$keyword); print "Loggin...\n" if($deb); $mech-submit_form(); $dest= $mech-response-content; if($mech-response-header("Content-Encoding") eq "gzip") { $dest = Compress::Zlib::memGunzip($dest); $mech-update_html($dest); } $mech-get("http://wwwl.way2sms.com//jsp/InstantSMS.jsp?val=0"); $dest= $mech-response-content; if($mech-response-header("Content-Encoding") eq "gzip") { $dest = Compress::Zlib::memGunzip($dest); $mech-update_html($dest); } print "Sending ... \n" if($deb); $mech-form_with_fields(("MobNo","textArea")); $mech-field("MobNo",$mobile); $mech-field("textArea",$text); $mech-submit_form(); if($mech-success()) { print "Done \n" if($deb); } else { print "Failed \n" if($deb); exit; } $dest = $mech-response-content; if($mech-response-header("Content-Encoding") eq "gzip") { $dest = Compress::Zlib::memGunzip($dest); #print $dest if($deb); } if($dest =~ m/successfully/sig) { print "Message sent successfully" if($deb); } exit; *In this code I face with an error saying There is no form with the requested fields at ./sms.pl line 65 Can't call method "value" on an undefined value at /usr/share/perl5/vendor_perl/WWW/Mechanize.pm line* 1348. Could any 1 guide me please

    Read the article

  • Solicit and unsolicit messages/events in window programming?

    - by AKN
    Can someone pls tell me do we have solic & unsolic message/events in MFC or window programming? In devices solic response and unsolic response is said as immediate response (like acknowledgement to commands) and late response (generated without any further commands being sent) respectively. Likewise can we say events as solic / unsolic based on immediate occurrence and late occurrence?

    Read the article

  • Why can't Perl's WWW::Machanize find the form by field names?

    - by FRESHTER
    #!/usr/bin/perl use WWW::Mechanize; use Compress::Zlib; my $mech = WWW::Mechanize->new(); my $username = ""; #fill in username here my $keyword = ""; #fill in password here my $mobile = $ARGV[0]; my $text = $ARGV[1]; $deb = 1; print length($text)."\n" if($deb); $text = $text."\n\n\n\n\n" if(length($text) < 135); $mech->get("http://wwwl.way2sms.com/content/index.html"); unless($mech->success()) { exit; } $dest = $mech->response->content; print "Fetching...\n" if($deb); if($mech->response->header("Content-Encoding") eq "gzip") { $dest = Compress::Zlib::memGunzip($dest); $mech->update_html($dest); } $dest =~ s/<form name="loginForm"/<form action='..\/auth.cl' name="loginForm"/g; $mech->update_html($dest); $mech->form_with_fields(("username","password")); $mech->field("username",$username); $mech->field("password",$keyword); print "Loggin...\n" if($deb); $mech->submit_form(); $dest= $mech->response->content; if($mech->response->header("Content-Encoding") eq "gzip") { $dest = Compress::Zlib::memGunzip($dest); $mech->update_html($dest); } $mech->get("http://wwwl.way2sms.com//jsp/InstantSMS.jsp?val=0"); $dest= $mech->response->content; if($mech->response->header("Content-Encoding") eq "gzip") { $dest = Compress::Zlib::memGunzip($dest); $mech->update_html($dest); } print "Sending ... \n" if($deb); $mech->form_with_fields(("MobNo","textArea")); $mech->field("MobNo",$mobile); $mech->field("textArea",$text); $mech->submit_form(); if($mech->success()) { print "Done \n" if($deb); } else { print "Failed \n" if($deb); exit; } $dest = $mech->response->content; if($mech->response->header("Content-Encoding") eq "gzip") { $dest = Compress::Zlib::memGunzip($dest); #print $dest if($deb); } if($dest =~ m/successfully/sig) { print "Message sent successfully" if($deb); } exit; When run this code halts with an error saying: There is no form with the requested fields at ./sms.pl line 65 Can't call method "value" on an undefined value at /usr/share/perl5/vendor_perl/WWW/Mechanize.pm line 1348.

    Read the article

  • resttemplate getForObject map responsetype

    - by Zack Macomber
    I'm invoking a rest service that returns JSON like this: { "some.key" : "some value", "another.key" : "another value" } I would like to think that I can invoke this service with a java.util.Map as the response type but that's not working for me. I get this exception: org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [interface java.util.Map] Should I just specify String as the response type and convert the JSON to a Map?

    Read the article

  • C# Persistent WebClient

    - by Nullstr1ng
    I have a class written in C# (Windows Forms) It's a WebClient class which I intent to use in some website and for Logging In and navigation. Here's the complete class pastebin.com (the class has 197 lines so I just use pastebin. Sorry if I made a little bit harder for you to read the class, also below this post) The problem is, am not sure why it's not persistent .. I was able to log in, but when I navigate to other page (without leaving the domain), I was thrown back to log in page. Can you help me solving this problem? one issue though is, the site I was trying to connect is "HTTPS" protocol. I have not yet tested this on just a regular HTTP. Thank you in advance. /* * Web Client v1.2 * --------------- * Date: 12/17/2010 * author: Jayson Ragasa */ using System; using System.Collections; using System.Collections.Specialized; using System.Collections.Generic; using System.Text; using System.IO; using System.Net; using System.Web; namespace Nullstring.Modules.WebClient { public class WebClientLibrary { #region vars string _method = string.Empty; ArrayList _params; CookieContainer cookieko; HttpWebRequest req = null; HttpWebResponse resp = null; Uri uri = null; #endregion #region properties public string Method { set { _method = value; } } #endregion #region constructor public WebClientLibrary() { _method = "GET"; _params = new ArrayList(); cookieko = new CookieContainer(); } #endregion #region methods public void ClearParameter() { _params.Clear(); } public void AddParameter(string key, string value) { _params.Add(string.Format("{0}={1}", WebTools.URLEncodeString(key), WebTools.URLEncodeString(value))); } public string GetResponse(string URL) { StringBuilder response = new StringBuilder(); #region create web request { uri = new Uri(URL); req = (HttpWebRequest)WebRequest.Create(URL); req.Method = "GET"; req.GetLifetimeService(); } #endregion #region get web response { resp = (HttpWebResponse)req.GetResponse(); Stream resStream = resp.GetResponseStream(); int bytesReceived = 0; string tempString = null; int count = 0; byte[] buf = new byte[8192]; do { count = resStream.Read(buf, 0, buf.Length); if (count != 0) { bytesReceived += count; tempString = Encoding.UTF8.GetString(buf, 0, count); response.Append(tempString); } } while (count > 0); } #endregion return response.ToString(); } public string GetResponse(string URL, bool HasParams) { StringBuilder response = new StringBuilder(); #region create web request { uri = new Uri(URL); req = (HttpWebRequest)WebRequest.Create(URL); req.MaximumAutomaticRedirections = 20; req.AllowAutoRedirect = true; req.Method = this._method; req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; req.KeepAlive = true; req.CookieContainer = this.cookieko; req.UserAgent = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.224 Safari/534.10"; } #endregion #region build post data { if (HasParams) { if (this._method.ToUpper() == "POST") { string Parameters = String.Join("&", (String[])this._params.ToArray(typeof(string))); UTF8Encoding encoding = new UTF8Encoding(); byte[] loginDataBytes = encoding.GetBytes(Parameters); req.ContentType = "application/x-www-form-urlencoded"; req.ContentLength = loginDataBytes.Length; Stream stream = req.GetRequestStream(); stream.Write(loginDataBytes, 0, loginDataBytes.Length); stream.Close(); } } } #endregion #region get web response { resp = (HttpWebResponse)req.GetResponse(); Stream resStream = resp.GetResponseStream(); int bytesReceived = 0; string tempString = null; int count = 0; byte[] buf = new byte[8192]; do { count = resStream.Read(buf, 0, buf.Length); if (count != 0) { bytesReceived += count; tempString = Encoding.UTF8.GetString(buf, 0, count); response.Append(tempString); } } while (count > 0); } #endregion return response.ToString(); } #endregion } public class WebTools { public static string EncodeString(string str) { return HttpUtility.HtmlEncode(str); } public static string DecodeString(string str) { return HttpUtility.HtmlDecode(str); } public static string URLEncodeString(string str) { return HttpUtility.UrlEncode(str); } public static string URLDecodeString(string str) { return HttpUtility.UrlDecode(str); } } } UPDATE Dec 22GetResponse overload public string GetResponse(string URL) { StringBuilder response = new StringBuilder(); #region create web request { //uri = new Uri(URL); req = (HttpWebRequest)WebRequest.Create(URL); req.Method = "GET"; req.CookieContainer = this.cookieko; } #endregion #region get web response { resp = (HttpWebResponse)req.GetResponse(); Stream resStream = resp.GetResponseStream(); int bytesReceived = 0; string tempString = null; int count = 0; byte[] buf = new byte[8192]; do { count = resStream.Read(buf, 0, buf.Length); if (count != 0) { bytesReceived += count; tempString = Encoding.UTF8.GetString(buf, 0, count); response.Append(tempString); } } while (count 0); } #endregion return response.ToString(); } But still I got thrown back to login page. UPDATE: Dec 23 I tried listing the cookie and here's what I get at first, I have to login to a webform and this I have this Cookie JSESSIONID=368C0AC47305282CBCE7A566567D2942 then I navigated to another page (but on the same domain) I got a different Cooke? JSESSIONID=9FA2D64DA7669155B9120790B40A592C What went wrong? I use the code updated last Dec 22

    Read the article

  • Parsing JSON with eval

    - by Neethusha
    I have this code: function useHttpResponse() { if (xmlhttp.readyState==4 ) { var response = eval('('+xmlhttp.responseText+')'); alert(response); for(i=0;i<response.Users.length;i++) alert(response.Users[i].UserId); } } When i alert, the first alert is "[object Object]" Why is that so? I need to remove that...how?

    Read the article

  • No form with the requested fields?

    - by FRESHTER
    // #!/usr/bin/perl use WWW::Mechanize; use Compress::Zlib; my $mech = WWW::Mechanize->new(); my $username = ""; #fill in username here my $keyword = ""; #fill in password here my $mobile = $ARGV[0]; my $text = $ARGV[1]; $deb = 1; print length($text)."\n" if($deb); $text = $text."\n\n\n\n\n" if(length($text) < 135); $mech->get("http://wwwl.way2sms.com/content/index.html"); unless($mech->success()) { exit; } $dest = $mech->response->content; print "Fetching...\n" if($deb); if($mech->response->header("Content-Encoding") eq "gzip") { $dest = Compress::Zlib::memGunzip($dest); $mech->update_html($dest); } $dest =~ s/<form name="loginForm"/<form action='..\/auth.cl' name="loginForm"/g; $mech->update_html($dest); $mech->form_with_fields(("username","password")); $mech->field("username",$username); $mech->field("password",$keyword); print "Loggin...\n" if($deb); $mech->submit_form(); $dest= $mech->response->content; if($mech->response->header("Content-Encoding") eq "gzip") { $dest = Compress::Zlib::memGunzip($dest); $mech->update_html($dest); } $mech->get("http://wwwl.way2sms.com//jsp/InstantSMS.jsp?val=0"); $dest= $mech->response->content; if($mech->response->header("Content-Encoding") eq "gzip") { $dest = Compress::Zlib::memGunzip($dest); $mech->update_html($dest); } print "Sending ... \n" if($deb); $mech->form_with_fields(("MobNo","textArea")); $mech->field("MobNo",$mobile); $mech->field("textArea",$text); $mech->submit_form(); if($mech->success()) { print "Done \n" if($deb); } else { print "Failed \n" if($deb); exit; } $dest = $mech->response->content; if($mech->response->header("Content-Encoding") eq "gzip") { $dest = Compress::Zlib::memGunzip($dest); #print $dest if($deb); } if($dest =~ m/successfully/sig) { print "Message sent successfully" if($deb); } exit; *In this code I face with an error saying There is no form with the requested fields at ./sms.pl line 65 Can't call method "value" on an undefined value at /usr/share/perl5/vendor_perl/WWW/Mechanize.pm line* 1348. Could any 1 guide me please

    Read the article

  • increase a field value based on the radio button selection

    - by sts
    <% count = 1 % <% for question in @questions % <%=count%. <%= question.title if question.title% <% for response in @response % <% if response.question_id.eql?(question.id) % <%=radio_button(count, :voting, :count_modification) % <%= response.nomination % <% end % <% end % <% count += 1 % <% end % This is my whole code to implment the survey in views. if i give the count as third argument in radio button i cant select answer for each question. i can select only one answer for the whole survey.

    Read the article

  • How do I pass a multi-dimensional array as a GET parameter in PHP?

    - by Onema
    I have the following code. $connect = new Connection (); $response = $connect->putFile($fileName, $destination); header("Location: /test.php?response=" . $response); When I invoke header with the response, the file will stop execution, but I will have no error in the console... I am thinking maybe this array needs to be encoded for the url? if that is the case how? Thank you

    Read the article

  • Get the value of an attribute Jquery

    - by Abu Hamzah
    i am trying to get EmployeeId withitn the DOM something like this: var o = obj[$(this).attr("EmployeeId")]; but getting undefined when i debug i see the following: $(this)[0].data data "{EmployeeId: 'A42345'}" here is my source code: $.ajax({ type: "POST", url: url, data: "{EmployeeId: '" + id + "'}", contentType: "application/json; charset=utf-8", dataType: "json", success: function (response) { var obj = (typeof response.d) == 'string' ? eval('(' + response.d + ')') : response.d; var o = obj[$(this).attr("EmployeeId")]; //<<<<undefined

    Read the article

  • Cannot redirect after HTTP headers have been sent.

    - by Anilkumar
    When I try to redirect to another page through Response.Redirect(URL) am getting the following error:- System.Web.HttpException: Cannot redirect after HTTP headers have been sent. I wrote one Response.Write("Sometext"); and Response.Flush() before calling redirect Method. In this case how do we use Response.Redirect(URL)?

    Read the article

  • Is there anything called solicit and unsolicit messages/events in window programming?

    - by AKN
    Can someone pls tell me do we have solic & unsolic message/events in MFC or window programming? In devices solic response and unsolic response is said as immediate response (like acknowledgement to commands) and late response (generated without any further commands being sent) respectively. Likewise can we say events as solic / unsolic based on immediate occurrence and late occurrence?

    Read the article

  • Can you call FB.login inside a callback from other FB methods (like FB.getLoginStatus) without triggering popup blockers?

    - by Erik Kallevig
    I'm trying to set up a pretty basic authentication logic flow with the FB JavaScript SDK to check a user's logged-in status and permissions before performing an action (and prompting the user to login with permissions if they are not)... User types a message into a textarea on my site to post to their Facebook feed and click's a 'post to facebook' button on my site. In response to the click, I check user's logged in status with FB.getLoginStatus In the callback to FB.getLoginStatus, if user is not logged in, prompt them to login (FB.login). In the callback to FB.login I then need to make sure they have the right permissions so I make a call to FB.api('/me/permissions') -- if they don't , I again prompt them to login (FB.login) The problem I'm running into is that anytime I try to call FB.login inside a callback to other FB methods, the browser seems to lose track of the origin of execution (the click) and thus will block the popup. I'm wondering if I'm missing some way to prompt the user to login after checking their status without the browser mistakenly thinking that it's not a user-initiated popup? I've currently fallen back to just calling FB.login() first regardless. The undesired side effect of this approach, however, is that if the user is already logged-in with permissions and I'm still calling FB.login, the auth popup will open and close immediately before continuing, which looks rather buggy despite being functional. It seems like checking a user's login status and permissions before doing something would be a common flow so I feel like I'm missing something. Here's some example code. <div onclick="onClickPostBtn()">Post to Facebook</div> <script> // Callback to click on Post button. function onClickPostBtn() { // Check if logged in, prompt to do so if not. FB.getLoginStatus(function(response) { if (response.status === 'connected') { checkPermissions(response.authResponse.accessToken); } else { FB.login(function(){}, {scope: 'publish_stream'}) } }); } // Logged in, check permissions. function checkPermissions(accessToken) { FB.api('/me/permissions', {'access_token': accessToken}, function(response){ // Logged in and authorized for this site. if (response.data && response.data.length) { // Parse response object to check for permission here... if (hasPermission) { // Logged in with permission, perform some action. } else { // Logged in without proper permission, request login with permissions. FB.login(function(){}, {scope: 'publish_stream'}) } // Logged in to FB but not authorized for this site. } else { FB.login(function(){}, {scope: 'publish_stream'}) } } ); } </script>

    Read the article

  • Add if else function in Ajax Jquery function

    - by Naga Botak
    Is it possible to add other else function in my JS like this: ? if response == success redirect to home if response == failed redirect to failed $.ajax({ type: "POST", url: action, data: form_data, success: function(response) { if(response == 'success') window.location.replace("home"); else $("#message").html("<div class='error_log'><p class='error'>Invalid username and/or password.</p></div>"); } });

    Read the article

  • PHP: constant as variable in function

    - by m4recek
    I'm trying to use constant as a function paramter, is it possible to check type of this constant. Example of what I want: class ApiError { const INVALID_REQUEST = 200; } class Response { public function status(ApiError $status) { //function code here } } USE: $response = new Response(); $response->status(ApiError::INVALID_REQUEST); This shoud check that given $status is constant of class ApiError. Is something like this possible?

    Read the article

  • Introduction to the ASP.NET Web API

    - by Stephen.Walther
    I am a huge fan of Ajax. If you want to create a great experience for the users of your website – regardless of whether you are building an ASP.NET MVC or an ASP.NET Web Forms site — then you need to use Ajax. Otherwise, you are just being cruel to your customers. We use Ajax extensively in several of the ASP.NET applications that my company, Superexpert.com, builds. We expose data from the server as JSON and use jQuery to retrieve and update that data from the browser. One challenge, when building an ASP.NET website, is deciding on which technology to use to expose JSON data from the server. For example, how do you expose a list of products from the server as JSON so you can retrieve the list of products with jQuery? You have a number of options (too many options) including ASMX Web services, WCF Web Services, ASHX Generic Handlers, WCF Data Services, and MVC controller actions. Fortunately, the world has just been simplified. With the release of ASP.NET 4 Beta, Microsoft has introduced a new technology for exposing JSON from the server named the ASP.NET Web API. You can use the ASP.NET Web API with both ASP.NET MVC and ASP.NET Web Forms applications. The goal of this blog post is to provide you with a brief overview of the features of the new ASP.NET Web API. You learn how to use the ASP.NET Web API to retrieve, insert, update, and delete database records with jQuery. We also discuss how you can perform form validation when using the Web API and use OData when using the Web API. Creating an ASP.NET Web API Controller The ASP.NET Web API exposes JSON data through a new type of controller called an API controller. You can add an API controller to an existing ASP.NET MVC 4 project through the standard Add Controller dialog box. Right-click your Controllers folder and select Add, Controller. In the dialog box, name your controller MovieController and select the Empty API controller template: A brand new API controller looks like this: using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Web.Http; namespace MyWebAPIApp.Controllers { public class MovieController : ApiController { } } An API controller, unlike a standard MVC controller, derives from the base ApiController class instead of the base Controller class. Using jQuery to Retrieve, Insert, Update, and Delete Data Let’s create an Ajaxified Movie Database application. We’ll retrieve, insert, update, and delete movies using jQuery with the MovieController which we just created. Our Movie model class looks like this: namespace MyWebAPIApp.Models { public class Movie { public int Id { get; set; } public string Title { get; set; } public string Director { get; set; } } } Our application will consist of a single HTML page named Movies.html. We’ll place all of our jQuery code in the Movies.html page. Getting a Single Record with the ASP.NET Web API To support retrieving a single movie from the server, we need to add a Get method to our API controller: using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using MyWebAPIApp.Models; namespace MyWebAPIApp.Controllers { public class MovieController : ApiController { public Movie GetMovie(int id) { // Return movie by id if (id == 1) { return new Movie { Id = 1, Title = "Star Wars", Director = "Lucas" }; } // Otherwise, movie was not found throw new HttpResponseException(HttpStatusCode.NotFound); } } } In the code above, the GetMovie() method accepts the Id of a movie. If the Id has the value 1 then the method returns the movie Star Wars. Otherwise, the method throws an exception and returns 404 Not Found HTTP status code. After building your project, you can invoke the MovieController.GetMovie() method by entering the following URL in your web browser address bar: http://localhost:[port]/api/movie/1 (You’ll need to enter the correct randomly generated port). In the URL api/movie/1, the first “api” segment indicates that this is a Web API route. The “movie” segment indicates that the MovieController should be invoked. You do not specify the name of the action. Instead, the HTTP method used to make the request – GET, POST, PUT, DELETE — is used to identify the action to invoke. The ASP.NET Web API uses different routing conventions than normal ASP.NET MVC controllers. When you make an HTTP GET request then any API controller method with a name that starts with “GET” is invoked. So, we could have called our API controller action GetPopcorn() instead of GetMovie() and it would still be invoked by the URL api/movie/1. The default route for the Web API is defined in the Global.asax file and it looks like this: routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); We can invoke our GetMovie() controller action with the jQuery code in the following HTML page: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Get Movie</title> </head> <body> <div> Title: <span id="title"></span> </div> <div> Director: <span id="director"></span> </div> <script type="text/javascript" src="Scripts/jquery-1.6.2.min.js"></script> <script type="text/javascript"> getMovie(1, function (movie) { $("#title").html(movie.Title); $("#director").html(movie.Director); }); function getMovie(id, callback) { $.ajax({ url: "/api/Movie", data: { id: id }, type: "GET", contentType: "application/json;charset=utf-8", statusCode: { 200: function (movie) { callback(movie); }, 404: function () { alert("Not Found!"); } } }); } </script> </body> </html> In the code above, the jQuery $.ajax() method is used to invoke the GetMovie() method. Notice that the Ajax call handles two HTTP response codes. When the GetMove() method successfully returns a movie, the method returns a 200 status code. In that case, the details of the movie are displayed in the HTML page. Otherwise, if the movie is not found, the GetMovie() method returns a 404 status code. In that case, the page simply displays an alert box indicating that the movie was not found (hopefully, you would implement something more graceful in an actual application). You can use your browser’s Developer Tools to see what is going on in the background when you open the HTML page (hit F12 in the most recent version of most browsers). For example, you can use the Network tab in Google Chrome to see the Ajax request which invokes the GetMovie() method: Getting a Set of Records with the ASP.NET Web API Let’s modify our Movie API controller so that it returns a collection of movies. The following Movie controller has a new ListMovies() method which returns a (hard-coded) collection of movies: using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using MyWebAPIApp.Models; namespace MyWebAPIApp.Controllers { public class MovieController : ApiController { public IEnumerable<Movie> ListMovies() { return new List<Movie> { new Movie {Id=1, Title="Star Wars", Director="Lucas"}, new Movie {Id=1, Title="King Kong", Director="Jackson"}, new Movie {Id=1, Title="Memento", Director="Nolan"} }; } } } Because we named our action ListMovies(), the default Web API route will never match it. Therefore, we need to add the following custom route to our Global.asax file (at the top of the RegisterRoutes() method): routes.MapHttpRoute( name: "ActionApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional } ); This route enables us to invoke the ListMovies() method with the URL /api/movie/listmovies. Now that we have exposed our collection of movies from the server, we can retrieve and display the list of movies using jQuery in our HTML page: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>List Movies</title> </head> <body> <div id="movies"></div> <script type="text/javascript" src="Scripts/jquery-1.6.2.min.js"></script> <script type="text/javascript"> listMovies(function (movies) { var strMovies=""; $.each(movies, function (index, movie) { strMovies += "<div>" + movie.Title + "</div>"; }); $("#movies").html(strMovies); }); function listMovies(callback) { $.ajax({ url: "/api/Movie/ListMovies", data: {}, type: "GET", contentType: "application/json;charset=utf-8", }).then(function(movies){ callback(movies); }); } </script> </body> </html>     Inserting a Record with the ASP.NET Web API Now let’s modify our Movie API controller so it supports creating new records: public HttpResponseMessage<Movie> PostMovie(Movie movieToCreate) { // Add movieToCreate to the database and update primary key movieToCreate.Id = 23; // Build a response that contains the location of the new movie var response = new HttpResponseMessage<Movie>(movieToCreate, HttpStatusCode.Created); var relativePath = "/api/movie/" + movieToCreate.Id; response.Headers.Location = new Uri(Request.RequestUri, relativePath); return response; } The PostMovie() method in the code above accepts a movieToCreate parameter. We don’t actually store the new movie anywhere. In real life, you will want to call a service method to store the new movie in a database. When you create a new resource, such as a new movie, you should return the location of the new resource. In the code above, the URL where the new movie can be retrieved is assigned to the Location header returned in the PostMovie() response. Because the name of our method starts with “Post”, we don’t need to create a custom route. The PostMovie() method can be invoked with the URL /Movie/PostMovie – just as long as the method is invoked within the context of a HTTP POST request. The following HTML page invokes the PostMovie() method. <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Create Movie</title> </head> <body> <script type="text/javascript" src="Scripts/jquery-1.6.2.min.js"></script> <script type="text/javascript"> var movieToCreate = { title: "The Hobbit", director: "Jackson" }; createMovie(movieToCreate, function (newMovie) { alert("New movie created with an Id of " + newMovie.Id); }); function createMovie(movieToCreate, callback) { $.ajax({ url: "/api/Movie", data: JSON.stringify( movieToCreate ), type: "POST", contentType: "application/json;charset=utf-8", statusCode: { 201: function (newMovie) { callback(newMovie); } } }); } </script> </body> </html> This page creates a new movie (the Hobbit) by calling the createMovie() method. The page simply displays the Id of the new movie: The HTTP Post operation is performed with the following call to the jQuery $.ajax() method: $.ajax({ url: "/api/Movie", data: JSON.stringify( movieToCreate ), type: "POST", contentType: "application/json;charset=utf-8", statusCode: { 201: function (newMovie) { callback(newMovie); } } }); Notice that the type of Ajax request is a POST request. This is required to match the PostMovie() method. Notice, furthermore, that the new movie is converted into JSON using JSON.stringify(). The JSON.stringify() method takes a JavaScript object and converts it into a JSON string. Finally, notice that success is represented with a 201 status code. The HttpStatusCode.Created value returned from the PostMovie() method returns a 201 status code. Updating a Record with the ASP.NET Web API Here’s how we can modify the Movie API controller to support updating an existing record. In this case, we need to create a PUT method to handle an HTTP PUT request: public void PutMovie(Movie movieToUpdate) { if (movieToUpdate.Id == 1) { // Update the movie in the database return; } // If you can't find the movie to update throw new HttpResponseException(HttpStatusCode.NotFound); } Unlike our PostMovie() method, the PutMovie() method does not return a result. The action either updates the database or, if the movie cannot be found, returns an HTTP Status code of 404. The following HTML page illustrates how you can invoke the PutMovie() method: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Put Movie</title> </head> <body> <script type="text/javascript" src="Scripts/jquery-1.6.2.min.js"></script> <script type="text/javascript"> var movieToUpdate = { id: 1, title: "The Hobbit", director: "Jackson" }; updateMovie(movieToUpdate, function () { alert("Movie updated!"); }); function updateMovie(movieToUpdate, callback) { $.ajax({ url: "/api/Movie", data: JSON.stringify(movieToUpdate), type: "PUT", contentType: "application/json;charset=utf-8", statusCode: { 200: function () { callback(); }, 404: function () { alert("Movie not found!"); } } }); } </script> </body> </html> Deleting a Record with the ASP.NET Web API Here’s the code for deleting a movie: public HttpResponseMessage DeleteMovie(int id) { // Delete the movie from the database // Return status code return new HttpResponseMessage(HttpStatusCode.NoContent); } This method simply deletes the movie (well, not really, but pretend that it does) and returns a No Content status code (204). The following page illustrates how you can invoke the DeleteMovie() action: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Delete Movie</title> </head> <body> <script type="text/javascript" src="Scripts/jquery-1.6.2.min.js"></script> <script type="text/javascript"> deleteMovie(1, function () { alert("Movie deleted!"); }); function deleteMovie(id, callback) { $.ajax({ url: "/api/Movie", data: JSON.stringify({id:id}), type: "DELETE", contentType: "application/json;charset=utf-8", statusCode: { 204: function () { callback(); } } }); } </script> </body> </html> Performing Validation How do you perform form validation when using the ASP.NET Web API? Because validation in ASP.NET MVC is driven by the Default Model Binder, and because the Web API uses the Default Model Binder, you get validation for free. Let’s modify our Movie class so it includes some of the standard validation attributes: using System.ComponentModel.DataAnnotations; namespace MyWebAPIApp.Models { public class Movie { public int Id { get; set; } [Required(ErrorMessage="Title is required!")] [StringLength(5, ErrorMessage="Title cannot be more than 5 characters!")] public string Title { get; set; } [Required(ErrorMessage="Director is required!")] public string Director { get; set; } } } In the code above, the Required validation attribute is used to make both the Title and Director properties required. The StringLength attribute is used to require the length of the movie title to be no more than 5 characters. Now let’s modify our PostMovie() action to validate a movie before adding the movie to the database: public HttpResponseMessage PostMovie(Movie movieToCreate) { // Validate movie if (!ModelState.IsValid) { var errors = new JsonArray(); foreach (var prop in ModelState.Values) { if (prop.Errors.Any()) { errors.Add(prop.Errors.First().ErrorMessage); } } return new HttpResponseMessage<JsonValue>(errors, HttpStatusCode.BadRequest); } // Add movieToCreate to the database and update primary key movieToCreate.Id = 23; // Build a response that contains the location of the new movie var response = new HttpResponseMessage<Movie>(movieToCreate, HttpStatusCode.Created); var relativePath = "/api/movie/" + movieToCreate.Id; response.Headers.Location = new Uri(Request.RequestUri, relativePath); return response; } If ModelState.IsValid has the value false then the errors in model state are copied to a new JSON array. Each property – such as the Title and Director property — can have multiple errors. In the code above, only the first error message is copied over. The JSON array is returned with a Bad Request status code (400 status code). The following HTML page illustrates how you can invoke our modified PostMovie() action and display any error messages: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Create Movie</title> </head> <body> <script type="text/javascript" src="Scripts/jquery-1.6.2.min.js"></script> <script type="text/javascript"> var movieToCreate = { title: "The Hobbit", director: "" }; createMovie(movieToCreate, function (newMovie) { alert("New movie created with an Id of " + newMovie.Id); }, function (errors) { var strErrors = ""; $.each(errors, function(index, err) { strErrors += "*" + err + "\n"; }); alert(strErrors); } ); function createMovie(movieToCreate, success, fail) { $.ajax({ url: "/api/Movie", data: JSON.stringify(movieToCreate), type: "POST", contentType: "application/json;charset=utf-8", statusCode: { 201: function (newMovie) { success(newMovie); }, 400: function (xhr) { var errors = JSON.parse(xhr.responseText); fail(errors); } } }); } </script> </body> </html> The createMovie() function performs an Ajax request and handles either a 201 or a 400 status code from the response. If a 201 status code is returned then there were no validation errors and the new movie was created. If, on the other hand, a 400 status code is returned then there was a validation error. The validation errors are retrieved from the XmlHttpRequest responseText property. The error messages are displayed in an alert: (Please don’t use JavaScript alert dialogs to display validation errors, I just did it this way out of pure laziness) This validation code in our PostMovie() method is pretty generic. There is nothing specific about this code to the PostMovie() method. In the following video, Jon Galloway demonstrates how to create a global Validation filter which can be used with any API controller action: http://www.asp.net/web-api/overview/web-api-routing-and-actions/video-custom-validation His validation filter looks like this: using System.Json; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http.Controllers; using System.Web.Http.Filters; namespace MyWebAPIApp.Filters { public class ValidationActionFilter:ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { var modelState = actionContext.ModelState; if (!modelState.IsValid) { dynamic errors = new JsonObject(); foreach (var key in modelState.Keys) { var state = modelState[key]; if (state.Errors.Any()) { errors[key] = state.Errors.First().ErrorMessage; } } actionContext.Response = new HttpResponseMessage<JsonValue>(errors, HttpStatusCode.BadRequest); } } } } And you can register the validation filter in the Application_Start() method in the Global.asax file like this: GlobalConfiguration.Configuration.Filters.Add(new ValidationActionFilter()); After you register the Validation filter, validation error messages are returned from any API controller action method automatically when validation fails. You don’t need to add any special logic to any of your API controller actions to take advantage of the filter. Querying using OData The OData protocol is an open protocol created by Microsoft which enables you to perform queries over the web. The official website for OData is located here: http://odata.org For example, here are some of the query options which you can use with OData: · $orderby – Enables you to retrieve results in a certain order. · $top – Enables you to retrieve a certain number of results. · $skip – Enables you to skip over a certain number of results (use with $top for paging). · $filter – Enables you to filter the results returned. The ASP.NET Web API supports a subset of the OData protocol. You can use all of the query options listed above when interacting with an API controller. The only requirement is that the API controller action returns its data as IQueryable. For example, the following Movie controller has an action named GetMovies() which returns an IQueryable of movies: public IQueryable<Movie> GetMovies() { return new List<Movie> { new Movie {Id=1, Title="Star Wars", Director="Lucas"}, new Movie {Id=2, Title="King Kong", Director="Jackson"}, new Movie {Id=3, Title="Willow", Director="Lucas"}, new Movie {Id=4, Title="Shrek", Director="Smith"}, new Movie {Id=5, Title="Memento", Director="Nolan"} }.AsQueryable(); } If you enter the following URL in your browser: /api/movie?$top=2&$orderby=Title Then you will limit the movies returned to the top 2 in order of the movie Title. You will get the following results: By using the $top option in combination with the $skip option, you can enable client-side paging. For example, you can use $top and $skip to page through thousands of products, 10 products at a time. The $filter query option is very powerful. You can use this option to filter the results from a query. Here are some examples: Return every movie directed by Lucas: /api/movie?$filter=Director eq ‘Lucas’ Return every movie which has a title which starts with ‘S’: /api/movie?$filter=startswith(Title,’S') Return every movie which has an Id greater than 2: /api/movie?$filter=Id gt 2 The complete documentation for the $filter option is located here: http://www.odata.org/developers/protocols/uri-conventions#FilterSystemQueryOption Summary The goal of this blog entry was to provide you with an overview of the new ASP.NET Web API introduced with the Beta release of ASP.NET 4. In this post, I discussed how you can retrieve, insert, update, and delete data by using jQuery with the Web API. I also discussed how you can use the standard validation attributes with the Web API. You learned how to return validation error messages to the client and display the error messages using jQuery. Finally, we briefly discussed how the ASP.NET Web API supports the OData protocol. For example, you learned how to filter records returned from an API controller action by using the $filter query option. I’m excited about the new Web API. This is a feature which I expect to use with almost every ASP.NET application which I build in the future.

    Read the article

  • Introduction to the ASP.NET Web API

    - by Stephen.Walther
    I am a huge fan of Ajax. If you want to create a great experience for the users of your website – regardless of whether you are building an ASP.NET MVC or an ASP.NET Web Forms site — then you need to use Ajax. Otherwise, you are just being cruel to your customers. We use Ajax extensively in several of the ASP.NET applications that my company, Superexpert.com, builds. We expose data from the server as JSON and use jQuery to retrieve and update that data from the browser. One challenge, when building an ASP.NET website, is deciding on which technology to use to expose JSON data from the server. For example, how do you expose a list of products from the server as JSON so you can retrieve the list of products with jQuery? You have a number of options (too many options) including ASMX Web services, WCF Web Services, ASHX Generic Handlers, WCF Data Services, and MVC controller actions. Fortunately, the world has just been simplified. With the release of ASP.NET 4 Beta, Microsoft has introduced a new technology for exposing JSON from the server named the ASP.NET Web API. You can use the ASP.NET Web API with both ASP.NET MVC and ASP.NET Web Forms applications. The goal of this blog post is to provide you with a brief overview of the features of the new ASP.NET Web API. You learn how to use the ASP.NET Web API to retrieve, insert, update, and delete database records with jQuery. We also discuss how you can perform form validation when using the Web API and use OData when using the Web API. Creating an ASP.NET Web API Controller The ASP.NET Web API exposes JSON data through a new type of controller called an API controller. You can add an API controller to an existing ASP.NET MVC 4 project through the standard Add Controller dialog box. Right-click your Controllers folder and select Add, Controller. In the dialog box, name your controller MovieController and select the Empty API controller template: A brand new API controller looks like this: using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Web.Http; namespace MyWebAPIApp.Controllers { public class MovieController : ApiController { } } An API controller, unlike a standard MVC controller, derives from the base ApiController class instead of the base Controller class. Using jQuery to Retrieve, Insert, Update, and Delete Data Let’s create an Ajaxified Movie Database application. We’ll retrieve, insert, update, and delete movies using jQuery with the MovieController which we just created. Our Movie model class looks like this: namespace MyWebAPIApp.Models { public class Movie { public int Id { get; set; } public string Title { get; set; } public string Director { get; set; } } } Our application will consist of a single HTML page named Movies.html. We’ll place all of our jQuery code in the Movies.html page. Getting a Single Record with the ASP.NET Web API To support retrieving a single movie from the server, we need to add a Get method to our API controller: using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using MyWebAPIApp.Models; namespace MyWebAPIApp.Controllers { public class MovieController : ApiController { public Movie GetMovie(int id) { // Return movie by id if (id == 1) { return new Movie { Id = 1, Title = "Star Wars", Director = "Lucas" }; } // Otherwise, movie was not found throw new HttpResponseException(HttpStatusCode.NotFound); } } } In the code above, the GetMovie() method accepts the Id of a movie. If the Id has the value 1 then the method returns the movie Star Wars. Otherwise, the method throws an exception and returns 404 Not Found HTTP status code. After building your project, you can invoke the MovieController.GetMovie() method by entering the following URL in your web browser address bar: http://localhost:[port]/api/movie/1 (You’ll need to enter the correct randomly generated port). In the URL api/movie/1, the first “api” segment indicates that this is a Web API route. The “movie” segment indicates that the MovieController should be invoked. You do not specify the name of the action. Instead, the HTTP method used to make the request – GET, POST, PUT, DELETE — is used to identify the action to invoke. The ASP.NET Web API uses different routing conventions than normal ASP.NET MVC controllers. When you make an HTTP GET request then any API controller method with a name that starts with “GET” is invoked. So, we could have called our API controller action GetPopcorn() instead of GetMovie() and it would still be invoked by the URL api/movie/1. The default route for the Web API is defined in the Global.asax file and it looks like this: routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); We can invoke our GetMovie() controller action with the jQuery code in the following HTML page: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Get Movie</title> </head> <body> <div> Title: <span id="title"></span> </div> <div> Director: <span id="director"></span> </div> <script type="text/javascript" src="Scripts/jquery-1.6.2.min.js"></script> <script type="text/javascript"> getMovie(1, function (movie) { $("#title").html(movie.Title); $("#director").html(movie.Director); }); function getMovie(id, callback) { $.ajax({ url: "/api/Movie", data: { id: id }, type: "GET", contentType: "application/json;charset=utf-8", statusCode: { 200: function (movie) { callback(movie); }, 404: function () { alert("Not Found!"); } } }); } </script> </body> </html> In the code above, the jQuery $.ajax() method is used to invoke the GetMovie() method. Notice that the Ajax call handles two HTTP response codes. When the GetMove() method successfully returns a movie, the method returns a 200 status code. In that case, the details of the movie are displayed in the HTML page. Otherwise, if the movie is not found, the GetMovie() method returns a 404 status code. In that case, the page simply displays an alert box indicating that the movie was not found (hopefully, you would implement something more graceful in an actual application). You can use your browser’s Developer Tools to see what is going on in the background when you open the HTML page (hit F12 in the most recent version of most browsers). For example, you can use the Network tab in Google Chrome to see the Ajax request which invokes the GetMovie() method: Getting a Set of Records with the ASP.NET Web API Let’s modify our Movie API controller so that it returns a collection of movies. The following Movie controller has a new ListMovies() method which returns a (hard-coded) collection of movies: using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using MyWebAPIApp.Models; namespace MyWebAPIApp.Controllers { public class MovieController : ApiController { public IEnumerable<Movie> ListMovies() { return new List<Movie> { new Movie {Id=1, Title="Star Wars", Director="Lucas"}, new Movie {Id=1, Title="King Kong", Director="Jackson"}, new Movie {Id=1, Title="Memento", Director="Nolan"} }; } } } Because we named our action ListMovies(), the default Web API route will never match it. Therefore, we need to add the following custom route to our Global.asax file (at the top of the RegisterRoutes() method): routes.MapHttpRoute( name: "ActionApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional } ); This route enables us to invoke the ListMovies() method with the URL /api/movie/listmovies. Now that we have exposed our collection of movies from the server, we can retrieve and display the list of movies using jQuery in our HTML page: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>List Movies</title> </head> <body> <div id="movies"></div> <script type="text/javascript" src="Scripts/jquery-1.6.2.min.js"></script> <script type="text/javascript"> listMovies(function (movies) { var strMovies=""; $.each(movies, function (index, movie) { strMovies += "<div>" + movie.Title + "</div>"; }); $("#movies").html(strMovies); }); function listMovies(callback) { $.ajax({ url: "/api/Movie/ListMovies", data: {}, type: "GET", contentType: "application/json;charset=utf-8", }).then(function(movies){ callback(movies); }); } </script> </body> </html>     Inserting a Record with the ASP.NET Web API Now let’s modify our Movie API controller so it supports creating new records: public HttpResponseMessage<Movie> PostMovie(Movie movieToCreate) { // Add movieToCreate to the database and update primary key movieToCreate.Id = 23; // Build a response that contains the location of the new movie var response = new HttpResponseMessage<Movie>(movieToCreate, HttpStatusCode.Created); var relativePath = "/api/movie/" + movieToCreate.Id; response.Headers.Location = new Uri(Request.RequestUri, relativePath); return response; } The PostMovie() method in the code above accepts a movieToCreate parameter. We don’t actually store the new movie anywhere. In real life, you will want to call a service method to store the new movie in a database. When you create a new resource, such as a new movie, you should return the location of the new resource. In the code above, the URL where the new movie can be retrieved is assigned to the Location header returned in the PostMovie() response. Because the name of our method starts with “Post”, we don’t need to create a custom route. The PostMovie() method can be invoked with the URL /Movie/PostMovie – just as long as the method is invoked within the context of a HTTP POST request. The following HTML page invokes the PostMovie() method. <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Create Movie</title> </head> <body> <script type="text/javascript" src="Scripts/jquery-1.6.2.min.js"></script> <script type="text/javascript"> var movieToCreate = { title: "The Hobbit", director: "Jackson" }; createMovie(movieToCreate, function (newMovie) { alert("New movie created with an Id of " + newMovie.Id); }); function createMovie(movieToCreate, callback) { $.ajax({ url: "/api/Movie", data: JSON.stringify( movieToCreate ), type: "POST", contentType: "application/json;charset=utf-8", statusCode: { 201: function (newMovie) { callback(newMovie); } } }); } </script> </body> </html> This page creates a new movie (the Hobbit) by calling the createMovie() method. The page simply displays the Id of the new movie: The HTTP Post operation is performed with the following call to the jQuery $.ajax() method: $.ajax({ url: "/api/Movie", data: JSON.stringify( movieToCreate ), type: "POST", contentType: "application/json;charset=utf-8", statusCode: { 201: function (newMovie) { callback(newMovie); } } }); Notice that the type of Ajax request is a POST request. This is required to match the PostMovie() method. Notice, furthermore, that the new movie is converted into JSON using JSON.stringify(). The JSON.stringify() method takes a JavaScript object and converts it into a JSON string. Finally, notice that success is represented with a 201 status code. The HttpStatusCode.Created value returned from the PostMovie() method returns a 201 status code. Updating a Record with the ASP.NET Web API Here’s how we can modify the Movie API controller to support updating an existing record. In this case, we need to create a PUT method to handle an HTTP PUT request: public void PutMovie(Movie movieToUpdate) { if (movieToUpdate.Id == 1) { // Update the movie in the database return; } // If you can't find the movie to update throw new HttpResponseException(HttpStatusCode.NotFound); } Unlike our PostMovie() method, the PutMovie() method does not return a result. The action either updates the database or, if the movie cannot be found, returns an HTTP Status code of 404. The following HTML page illustrates how you can invoke the PutMovie() method: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Put Movie</title> </head> <body> <script type="text/javascript" src="Scripts/jquery-1.6.2.min.js"></script> <script type="text/javascript"> var movieToUpdate = { id: 1, title: "The Hobbit", director: "Jackson" }; updateMovie(movieToUpdate, function () { alert("Movie updated!"); }); function updateMovie(movieToUpdate, callback) { $.ajax({ url: "/api/Movie", data: JSON.stringify(movieToUpdate), type: "PUT", contentType: "application/json;charset=utf-8", statusCode: { 200: function () { callback(); }, 404: function () { alert("Movie not found!"); } } }); } </script> </body> </html> Deleting a Record with the ASP.NET Web API Here’s the code for deleting a movie: public HttpResponseMessage DeleteMovie(int id) { // Delete the movie from the database // Return status code return new HttpResponseMessage(HttpStatusCode.NoContent); } This method simply deletes the movie (well, not really, but pretend that it does) and returns a No Content status code (204). The following page illustrates how you can invoke the DeleteMovie() action: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Delete Movie</title> </head> <body> <script type="text/javascript" src="Scripts/jquery-1.6.2.min.js"></script> <script type="text/javascript"> deleteMovie(1, function () { alert("Movie deleted!"); }); function deleteMovie(id, callback) { $.ajax({ url: "/api/Movie", data: JSON.stringify({id:id}), type: "DELETE", contentType: "application/json;charset=utf-8", statusCode: { 204: function () { callback(); } } }); } </script> </body> </html> Performing Validation How do you perform form validation when using the ASP.NET Web API? Because validation in ASP.NET MVC is driven by the Default Model Binder, and because the Web API uses the Default Model Binder, you get validation for free. Let’s modify our Movie class so it includes some of the standard validation attributes: using System.ComponentModel.DataAnnotations; namespace MyWebAPIApp.Models { public class Movie { public int Id { get; set; } [Required(ErrorMessage="Title is required!")] [StringLength(5, ErrorMessage="Title cannot be more than 5 characters!")] public string Title { get; set; } [Required(ErrorMessage="Director is required!")] public string Director { get; set; } } } In the code above, the Required validation attribute is used to make both the Title and Director properties required. The StringLength attribute is used to require the length of the movie title to be no more than 5 characters. Now let’s modify our PostMovie() action to validate a movie before adding the movie to the database: public HttpResponseMessage PostMovie(Movie movieToCreate) { // Validate movie if (!ModelState.IsValid) { var errors = new JsonArray(); foreach (var prop in ModelState.Values) { if (prop.Errors.Any()) { errors.Add(prop.Errors.First().ErrorMessage); } } return new HttpResponseMessage<JsonValue>(errors, HttpStatusCode.BadRequest); } // Add movieToCreate to the database and update primary key movieToCreate.Id = 23; // Build a response that contains the location of the new movie var response = new HttpResponseMessage<Movie>(movieToCreate, HttpStatusCode.Created); var relativePath = "/api/movie/" + movieToCreate.Id; response.Headers.Location = new Uri(Request.RequestUri, relativePath); return response; } If ModelState.IsValid has the value false then the errors in model state are copied to a new JSON array. Each property – such as the Title and Director property — can have multiple errors. In the code above, only the first error message is copied over. The JSON array is returned with a Bad Request status code (400 status code). The following HTML page illustrates how you can invoke our modified PostMovie() action and display any error messages: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Create Movie</title> </head> <body> <script type="text/javascript" src="Scripts/jquery-1.6.2.min.js"></script> <script type="text/javascript"> var movieToCreate = { title: "The Hobbit", director: "" }; createMovie(movieToCreate, function (newMovie) { alert("New movie created with an Id of " + newMovie.Id); }, function (errors) { var strErrors = ""; $.each(errors, function(index, err) { strErrors += "*" + err + "n"; }); alert(strErrors); } ); function createMovie(movieToCreate, success, fail) { $.ajax({ url: "/api/Movie", data: JSON.stringify(movieToCreate), type: "POST", contentType: "application/json;charset=utf-8", statusCode: { 201: function (newMovie) { success(newMovie); }, 400: function (xhr) { var errors = JSON.parse(xhr.responseText); fail(errors); } } }); } </script> </body> </html> The createMovie() function performs an Ajax request and handles either a 201 or a 400 status code from the response. If a 201 status code is returned then there were no validation errors and the new movie was created. If, on the other hand, a 400 status code is returned then there was a validation error. The validation errors are retrieved from the XmlHttpRequest responseText property. The error messages are displayed in an alert: (Please don’t use JavaScript alert dialogs to display validation errors, I just did it this way out of pure laziness) This validation code in our PostMovie() method is pretty generic. There is nothing specific about this code to the PostMovie() method. In the following video, Jon Galloway demonstrates how to create a global Validation filter which can be used with any API controller action: http://www.asp.net/web-api/overview/web-api-routing-and-actions/video-custom-validation His validation filter looks like this: using System.Json; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http.Controllers; using System.Web.Http.Filters; namespace MyWebAPIApp.Filters { public class ValidationActionFilter:ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { var modelState = actionContext.ModelState; if (!modelState.IsValid) { dynamic errors = new JsonObject(); foreach (var key in modelState.Keys) { var state = modelState[key]; if (state.Errors.Any()) { errors[key] = state.Errors.First().ErrorMessage; } } actionContext.Response = new HttpResponseMessage<JsonValue>(errors, HttpStatusCode.BadRequest); } } } } And you can register the validation filter in the Application_Start() method in the Global.asax file like this: GlobalConfiguration.Configuration.Filters.Add(new ValidationActionFilter()); After you register the Validation filter, validation error messages are returned from any API controller action method automatically when validation fails. You don’t need to add any special logic to any of your API controller actions to take advantage of the filter. Querying using OData The OData protocol is an open protocol created by Microsoft which enables you to perform queries over the web. The official website for OData is located here: http://odata.org For example, here are some of the query options which you can use with OData: · $orderby – Enables you to retrieve results in a certain order. · $top – Enables you to retrieve a certain number of results. · $skip – Enables you to skip over a certain number of results (use with $top for paging). · $filter – Enables you to filter the results returned. The ASP.NET Web API supports a subset of the OData protocol. You can use all of the query options listed above when interacting with an API controller. The only requirement is that the API controller action returns its data as IQueryable. For example, the following Movie controller has an action named GetMovies() which returns an IQueryable of movies: public IQueryable<Movie> GetMovies() { return new List<Movie> { new Movie {Id=1, Title="Star Wars", Director="Lucas"}, new Movie {Id=2, Title="King Kong", Director="Jackson"}, new Movie {Id=3, Title="Willow", Director="Lucas"}, new Movie {Id=4, Title="Shrek", Director="Smith"}, new Movie {Id=5, Title="Memento", Director="Nolan"} }.AsQueryable(); } If you enter the following URL in your browser: /api/movie?$top=2&$orderby=Title Then you will limit the movies returned to the top 2 in order of the movie Title. You will get the following results: By using the $top option in combination with the $skip option, you can enable client-side paging. For example, you can use $top and $skip to page through thousands of products, 10 products at a time. The $filter query option is very powerful. You can use this option to filter the results from a query. Here are some examples: Return every movie directed by Lucas: /api/movie?$filter=Director eq ‘Lucas’ Return every movie which has a title which starts with ‘S’: /api/movie?$filter=startswith(Title,’S') Return every movie which has an Id greater than 2: /api/movie?$filter=Id gt 2 The complete documentation for the $filter option is located here: http://www.odata.org/developers/protocols/uri-conventions#FilterSystemQueryOption Summary The goal of this blog entry was to provide you with an overview of the new ASP.NET Web API introduced with the Beta release of ASP.NET 4. In this post, I discussed how you can retrieve, insert, update, and delete data by using jQuery with the Web API. I also discussed how you can use the standard validation attributes with the Web API. You learned how to return validation error messages to the client and display the error messages using jQuery. Finally, we briefly discussed how the ASP.NET Web API supports the OData protocol. For example, you learned how to filter records returned from an API controller action by using the $filter query option. I’m excited about the new Web API. This is a feature which I expect to use with almost every ASP.NET application which I build in the future.

    Read the article

  • Fed Authentication Methods in OIF / IdP

    - by Damien Carru
    This article is a continuation of my previous entry where I explained how OIF/IdP leverages OAM to authenticate users at runtime: OIF/IdP internally forwards the user to OAM and indicates which Authentication Scheme should be used to challenge the user if needed OAM determine if the user should be challenged (user already authenticated, session timed out or not, session authentication level equal or higher than the level of the authentication scheme specified by OIF/IdP…) After identifying the user, OAM internally forwards the user back to OIF/IdP OIF/IdP can resume its operation In this article, I will discuss how OIF/IdP can be configured to map Federation Authentication Methods to OAM Authentication Schemes: When processing an Authn Request, where the SP requests a specific Federation Authentication Method with which the user should be challenged When sending an Assertion, where OIF/IdP sets the Federation Authentication Method in the Assertion Enjoy the reading! Overview The various Federation protocols support mechanisms allowing the partners to exchange information on: How the user should be challenged, when the SP/RP makes a request How the user was challenged, when the IdP/OP issues an SSO response When a remote SP partner redirects the user to OIF/IdP for Federation SSO, the message might contain data requesting how the user should be challenged by the IdP: this is treated as the Requested Federation Authentication Method. OIF/IdP will need to map that Requested Federation Authentication Method to a local Authentication Scheme, and then invoke OAM for user authentication/challenge with the mapped Authentication Scheme. OAM would authenticate the user if necessary with the scheme specified by OIF/IdP. Similarly, when an IdP issues an SSO response, most of the time it will need to include an identifier representing how the user was challenged: this is treated as the Federation Authentication Method. When OIF/IdP issues an Assertion, it will evaluate the Authentication Scheme with which OAM identified the user: If the Authentication Scheme can be mapped to a Federation Authentication Method, then OIF/IdP will use the result of that mapping in the outgoing SSO response: AuthenticationStatement in the SAML Assertion OpenID Response, if PAPE is enabled If the Authentication Scheme cannot be mapped, then OIF/IdP will set the Federation Authentication Method as the Authentication Scheme name in the outgoing SSO response: AuthenticationStatement in the SAML Assertion OpenID Response, if PAPE is enabled Mappings In OIF/IdP, the mapping between Federation Authentication Methods and Authentication Schemes has the following rules: One Federation Authentication Method can be mapped to several Authentication Schemes In a Federation Authentication Method <-> Authentication Schemes mapping, a single Authentication Scheme is marked as the default scheme that will be used to authenticate a user, if the SP/RP partner requests the user to be authenticated via a specific Federation Authentication Method An Authentication Scheme can be mapped to a single Federation Authentication Method Let’s examine the following example and the various use cases, based on the SAML 2.0 protocol: Mappings defined as: urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport mapped to LDAPScheme, marked as the default scheme used for authentication BasicScheme urn:oasis:names:tc:SAML:2.0:ac:classes:X509 mapped to X509Scheme, marked as the default scheme used for authentication Use cases: SP sends an AuthnRequest specifying urn:oasis:names:tc:SAML:2.0:ac:classes:X509 as the RequestedAuthnContext: OIF/IdP will authenticate the use with X509Scheme since it is the default scheme mapped for that method. SP sends an AuthnRequest specifying urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport as the RequestedAuthnContext: OIF/IdP will authenticate the use with LDAPScheme since it is the default scheme mapped for that method, not the BasicScheme SP did not request any specific methods, and user was authenticated with BasisScheme: OIF/IdP will issue an Assertion with urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport as the FederationAuthenticationMethod SP did not request any specific methods, and user was authenticated with LDAPScheme: OIF/IdP will issue an Assertion with urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport as the FederationAuthenticationMethod SP did not request any specific methods, and user was authenticated with BasisSessionlessScheme: OIF/IdP will issue an Assertion with BasisSessionlessScheme as the FederationAuthenticationMethod, since that scheme could not be mapped to any Federation Authentication Method (in this case, the administrator would need to correct that and create a mapping) Configuration Mapping Federation Authentication Methods to OAM Authentication Schemes is protocol dependent, since the methods are defined in the various protocols (SAML 2.0, SAML 1.1, OpenID 2.0). As such, the WLST commands to set those mappings will involve: Either the SP Partner Profile and affect all Partners referencing that profile, which do not override the Federation Authentication Method to OAM Authentication Scheme mappings Or the SP Partner entry, which will only affect the SP Partner It is important to note that if an SP Partner is configured to define one or more Federation Authentication Method to OAM Authentication Scheme mappings, then all the mappings defined in the SP Partner Profile will be ignored. Authentication Schemes As discussed in the previous article, during Federation SSO, OIF/IdP will internally forward the user to OAM for authentication/verification and specify which Authentication Scheme to use. OAM will determine if a user needs to be challenged: If the user is not authenticated yet If the user is authenticated but the session timed out If the user is authenticated, but the authentication scheme level of the original authentication is lower than the level of the authentication scheme requested by OIF/IdP So even though an SP requests a specific Federation Authentication Method to be used to challenge the user, if that method is mapped to an Authentication Scheme and that at runtime OAM deems that the user does not need to be challenged with that scheme (because the user is already authenticated, session did not time out, and the session authn level is equal or higher than the one for the specified Authentication Scheme), the flow won’t result in a challenge operation. Protocols SAML 2.0 The SAML 2.0 specifications define the following Federation Authentication Methods for SAML 2.0 flows: urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified urn:oasis:names:tc:SAML:2.0:ac:classes:InternetProtocol urn:oasis:names:tc:SAML:2.0:ac:classes:Telephony urn:oasis:names:tc:SAML:2.0:ac:classes:MobileOneFactorUnregistered urn:oasis:names:tc:SAML:2.0:ac:classes:PersonalTelephony urn:oasis:names:tc:SAML:2.0:ac:classes:PreviousSession urn:oasis:names:tc:SAML:2.0:ac:classes:MobileOneFactorContract urn:oasis:names:tc:SAML:2.0:ac:classes:Smartcard urn:oasis:names:tc:SAML:2.0:ac:classes:Password urn:oasis:names:tc:SAML:2.0:ac:classes:InternetProtocolPassword urn:oasis:names:tc:SAML:2.0:ac:classes:X509 urn:oasis:names:tc:SAML:2.0:ac:classes:TLSClient urn:oasis:names:tc:SAML:2.0:ac:classes:PGP urn:oasis:names:tc:SAML:2.0:ac:classes:SPKI urn:oasis:names:tc:SAML:2.0:ac:classes:XMLDSig urn:oasis:names:tc:SAML:2.0:ac:classes:SoftwarePKI urn:oasis:names:tc:SAML:2.0:ac:classes:Kerberos urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport urn:oasis:names:tc:SAML:2.0:ac:classes:SecureRemotePassword urn:oasis:names:tc:SAML:2.0:ac:classes:NomadTelephony urn:oasis:names:tc:SAML:2.0:ac:classes:AuthenticatedTelephony urn:oasis:names:tc:SAML:2.0:ac:classes:MobileTwoFactorUnregistered urn:oasis:names:tc:SAML:2.0:ac:classes:MobileTwoFactorContract urn:oasis:names:tc:SAML:2.0:ac:classes:SmartcardPKI urn:oasis:names:tc:SAML:2.0:ac:classes:TimeSyncToken Out of the box, OIF/IdP has the following mappings for the SAML 2.0 protocol: Only urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport is defined This Federation Authentication Method is mapped to: LDAPScheme, marked as the default scheme used for authentication FAAuthScheme BasicScheme BasicFAScheme This mapping is defined in the saml20-sp-partner-profile SP Partner Profile which is the default OOTB SP Partner Profile for SAML 2.0 An example of an AuthnRequest message sent by an SP to an IdP with the SP requesting a specific Federation Authentication Method to be used to challenge the user would be: <samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://idp.com/oamfed/idp/samlv20" ID="id-8bWn-A9o4aoMl3Nhx1DuPOOjawc-" IssueInstant="2014-03-21T20:51:11Z" Version="2.0">  <saml:Issuer ...>https://acme.com/sp</saml:Issuer>  <samlp:NameIDPolicy AllowCreate="false" Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"/>  <samlp:RequestedAuthnContext Comparison="minimum">    <saml:AuthnContextClassRef xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">      urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport </saml:AuthnContextClassRef>  </samlp:RequestedAuthnContext></samlp:AuthnRequest> An example of an Assertion issued by an IdP would be: <samlp:Response ...>    <saml:Issuer ...>https://idp.com/oam/fed</saml:Issuer>    <samlp:Status>        <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>    </samlp:Status>    <saml:Assertion ...>        <saml:Issuer ...>https://idp.com/oam/fed</saml:Issuer>        <dsig:Signature>            ...        </dsig:Signature>        <saml:Subject>            <saml:NameID ...>[email protected]</saml:NameID>            <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">                <saml:SubjectConfirmationData .../>            </saml:SubjectConfirmation>        </saml:Subject>        <saml:Conditions ...>            <saml:AudienceRestriction>                <saml:Audience>https://acme.com/sp</saml:Audience>            </saml:AudienceRestriction>        </saml:Conditions>        <saml:AuthnStatement AuthnInstant="2014-03-21T20:53:55Z" SessionIndex="id-6i-Dm0yB-HekG6cejktwcKIFMzYE8Yrmqwfd0azz" SessionNotOnOrAfter="2014-03-21T21:53:55Z">            <saml:AuthnContext>                <saml:AuthnContextClassRef>                    urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport                </saml:AuthnContextClassRef>            </saml:AuthnContext>        </saml:AuthnStatement>    </saml:Assertion></samlp:Response> An administrator would be able to specify a mapping between a SAML 2.0 Federation Authentication Method and one or more OAM Authentication Schemes SAML 1.1 The SAML 1.1 specifications define the following Federation Authentication Methods for SAML 1.1 flows: urn:oasis:names:tc:SAML:1.0:am:unspecified urn:oasis:names:tc:SAML:1.0:am:HardwareToken urn:oasis:names:tc:SAML:1.0:am:password urn:oasis:names:tc:SAML:1.0:am:X509-PKI urn:ietf:rfc:2246 urn:oasis:names:tc:SAML:1.0:am:PGP urn:oasis:names:tc:SAML:1.0:am:SPKI urn:ietf:rfc:3075 urn:oasis:names:tc:SAML:1.0:am:XKMS urn:ietf:rfc:1510 urn:ietf:rfc:2945 Out of the box, OIF/IdP has the following mappings for the SAML 1.1 protocol: Only urn:oasis:names:tc:SAML:1.0:am:password is defined This Federation Authentication Method is mapped to: LDAPScheme, marked as the default scheme used for authentication FAAuthScheme BasicScheme BasicFAScheme This mapping is defined in the saml11-sp-partner-profile SP Partner Profile which is the default OOTB SP Partner Profile for SAML 1.1 An example of an Assertion issued by an IdP would be: <samlp:Response ...>    <samlp:Status>        <samlp:StatusCode Value="samlp:Success"/>    </samlp:Status>    <saml:Assertion Issuer="https://idp.com/oam/fed" ...>        <saml:Conditions ...>            <saml:AudienceRestriction>                <saml:Audience>https://acme.com/sp/ssov11</saml:Audience>            </saml:AudienceRestriction>        </saml:Conditions>        <saml:AuthnStatement AuthenticationInstant="2014-03-21T20:53:55Z" AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:password">            <saml:Subject>                <saml:NameID ...>[email protected]</saml:NameID>                <saml:SubjectConfirmation>                   <saml:ConfirmationMethod>                       urn:oasis:names:tc:SAML:1.0:cm:bearer                   </saml:ConfirmationMethod>                </saml:SubjectConfirmation>            </saml:Subject>        </saml:AuthnStatement>        <dsig:Signature>            ...        </dsig:Signature>    </saml:Assertion></samlp:Response> Note: SAML 1.1 does not define an AuthnRequest message. An administrator would be able to specify a mapping between a SAML 1.1 Federation Authentication Method and one or more OAM Authentication Schemes OpenID 2.0 The OpenID 2.0 PAPE specifications define the following Federation Authentication Methods for OpenID 2.0 flows: http://schemas.openid.net/pape/policies/2007/06/phishing-resistant http://schemas.openid.net/pape/policies/2007/06/multi-factor http://schemas.openid.net/pape/policies/2007/06/multi-factor-physical Out of the box, OIF/IdP does not define any mappings for the OpenID 2.0 Federation Authentication Methods. For OpenID 2.0, the configuration will involve mapping a list of OpenID 2.0 policies to a list of Authentication Schemes. An example of an OpenID 2.0 Request message sent by an SP/RP to an IdP/OP would be: https://idp.com/openid?openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.mode=checkid_setup&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.assoc_handle=id-6a5S6zhAKaRwQNUnjTKROREdAGSjWodG1el4xyz3&openid.return_to=https%3A%2F%2Facme.com%2Fopenid%3Frefid%3Did-9PKVXZmRxAeDYcgLqPm36ClzOMA-&openid.realm=https%3A%2F%2Facme.com%2Fopenid&openid.ns.ax=http%3A%2F%2Fopenid.net%2Fsrv%2Fax%2F1.0&openid.ax.mode=fetch_request&openid.ax.type.attr0=http%3A%2F%2Faxschema.org%2Fcontact%2Femail&openid.ax.if_available=attr0&openid.ns.pape=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fpape%2F1.0&openid.pape.max_auth_age=0 An example of an Open ID 2.0 SSO Response issued by an IdP/OP would be: https://acme.com/openid?refid=id-9PKVXZmRxAeDYcgLqPm36ClzOMA-&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.mode=id_res&openid.op_endpoint=https%3A%2F%2Fidp.com%2Fopenid&openid.claimed_id=https%3A%2F%2Fidp.com%2Fopenid%3Fid%3Did-38iCmmlAVEXPsFjnFVKArfn5RIiF75D5doorhEgqqPM%3D&openid.identity=https%3A%2F%2Fidp.com%2Fopenid%3Fid%3Did-38iCmmlAVEXPsFjnFVKArfn5RIiF75D5doorhEgqqPM%3D&openid.return_to=https%3A%2F%2Facme.com%2Fopenid%3Frefid%3Did-9PKVXZmRxAeDYcgLqPm36ClzOMA-&openid.response_nonce=2014-03-24T19%3A20%3A06Zid-YPa2kTNNFftZkgBb460jxJGblk2g--iNwPpDI7M1&openid.assoc_handle=id-6a5S6zhAKaRwQNUnjTKROREdAGSjWodG1el4xyz3&openid.ns.ax=http%3A%2F%2Fopenid.net%2Fsrv%2Fax%2F1.0&openid.ax.mode=fetch_response&openid.ax.type.attr0=http%3A%2F%2Fsession%2Fcount&openid.ax.value.attr0=1&openid.ax.type.attr1=http%3A%2F%2Fopenid.net%2Fschema%2FnamePerson%2Ffriendly&openid.ax.value.attr1=My+name+is+Bobby+Smith&openid.ax.type.attr2=http%3A%2F%2Fschemas.openid.net%2Fax%2Fapi%2Fuser_id&openid.ax.value.attr2=bob&openid.ax.type.attr3=http%3A%2F%2Faxschema.org%2Fcontact%2Femail&openid.ax.value.attr3=bob%40oracle.com&openid.ax.type.attr4=http%3A%2F%2Fsession%2Fipaddress&openid.ax.value.attr4=10.145.120.253&openid.ns.pape=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fpape%2F1.0&openid.pape.auth_time=2014-03-24T19%3A20%3A05Z&openid.pape.auth_policies=http%3A%2F%2Fschemas.openid.net%2Fpape%2Fpolicies%2F2007%2F06%2Fphishing-resistant&openid.signed=op_endpoint%2Cclaimed_id%2Cidentity%2Creturn_to%2Cresponse_nonce%2Cassoc_handle%2Cns.ax%2Cax.mode%2Cax.type.attr0%2Cax.value.attr0%2Cax.type.attr1%2Cax.value.attr1%2Cax.type.attr2%2Cax.value.attr2%2Cax.type.attr3%2Cax.value.attr3%2Cax.type.attr4%2Cax.value.attr4%2Cns.pape%2Cpape.auth_time%2Cpape.auth_policies&openid.sig=mYMgbGYSs22l8e%2FDom9NRPw15u8%3D In the next article, I will provide examples on how to configure OIF/IdP for the various protocols, to map OAM Authentication Schemes to Federation Authentication Methods.Cheers,Damien Carru

    Read the article

  • Radius Authorization against ActiveDirectory and the users file

    - by mohrphium
    I have a problem with my freeradius server configuration. I want to be able to authenticate users against Windows ActiveDirectory (2008 R2) and the users file, because some of my co-workers are not listed in AD. We use the freeradius server to authenticate WLAN users. (PEAP/MSCHAPv2) AD Authentication works great, but I still have problems with the /etc/freeradius/users file When I run freeradius -X -x I get the following: Mon Jul 2 09:15:58 2012 : Info: ++++[chap] returns noop Mon Jul 2 09:15:58 2012 : Info: ++++[mschap] returns noop Mon Jul 2 09:15:58 2012 : Info: [suffix] No '@' in User-Name = "testtest", looking up realm NULL Mon Jul 2 09:15:58 2012 : Info: [suffix] Found realm "NULL" Mon Jul 2 09:15:58 2012 : Info: [suffix] Adding Stripped-User-Name = "testtest" Mon Jul 2 09:15:58 2012 : Info: [suffix] Adding Realm = "NULL" Mon Jul 2 09:15:58 2012 : Info: [suffix] Authentication realm is LOCAL. Mon Jul 2 09:15:58 2012 : Info: ++++[suffix] returns ok Mon Jul 2 09:15:58 2012 : Info: [eap] EAP packet type response id 1 length 13 Mon Jul 2 09:15:58 2012 : Info: [eap] No EAP Start, assuming it's an on-going EAP conversation Mon Jul 2 09:15:58 2012 : Info: ++++[eap] returns updated Mon Jul 2 09:15:58 2012 : Info: [files] users: Matched entry testtest at line 1 Mon Jul 2 09:15:58 2012 : Info: ++++[files] returns ok Mon Jul 2 09:15:58 2012 : Info: ++++[expiration] returns noop Mon Jul 2 09:15:58 2012 : Info: ++++[logintime] returns noop Mon Jul 2 09:15:58 2012 : Info: [pap] WARNING: Auth-Type already set. Not setting to PAP Mon Jul 2 09:15:58 2012 : Info: ++++[pap] returns noop Mon Jul 2 09:15:58 2012 : Info: +++- else else returns updated Mon Jul 2 09:15:58 2012 : Info: ++- else else returns updated Mon Jul 2 09:15:58 2012 : Info: Found Auth-Type = EAP Mon Jul 2 09:15:58 2012 : Info: # Executing group from file /etc/freeradius/sites-enabled/default Mon Jul 2 09:15:58 2012 : Info: +- entering group authenticate {...} Mon Jul 2 09:15:58 2012 : Info: [eap] EAP Identity Mon Jul 2 09:15:58 2012 : Info: [eap] processing type tls Mon Jul 2 09:15:58 2012 : Info: [tls] Initiate Mon Jul 2 09:15:58 2012 : Info: [tls] Start returned 1 Mon Jul 2 09:15:58 2012 : Info: ++[eap] returns handled Sending Access-Challenge of id 199 to 192.168.61.11 port 3072 EAP-Message = 0x010200061920 Message-Authenticator = 0x00000000000000000000000000000000 State = 0x85469e2a854487589fb1196910cb8ae3 Mon Jul 2 09:15:58 2012 : Info: Finished request 125. Mon Jul 2 09:15:58 2012 : Debug: Going to the next request Mon Jul 2 09:15:58 2012 : Debug: Waking up in 2.4 seconds. After that it repeats the login attempt and at some point tries to authenticate against ActiveDirectory with ntlm, which doesn't work since the user exists only in the users file. Can someone help me out here? Thanks. PS: Hope this helps, freeradius trying to auth against AD: Mon Jul 2 09:15:58 2012 : Info: ++[chap] returns noop Mon Jul 2 09:15:58 2012 : Info: ++[mschap] returns noop Mon Jul 2 09:15:58 2012 : Info: [suffix] No '@' in User-Name = "testtest", looking up realm NULL Mon Jul 2 09:15:58 2012 : Info: [suffix] Found realm "NULL" Mon Jul 2 09:15:58 2012 : Info: [suffix] Adding Stripped-User-Name = "testtest" Mon Jul 2 09:15:58 2012 : Info: [suffix] Adding Realm = "NULL" Mon Jul 2 09:15:58 2012 : Info: [suffix] Authentication realm is LOCAL. Mon Jul 2 09:15:58 2012 : Info: ++[suffix] returns ok Mon Jul 2 09:15:58 2012 : Info: ++[control] returns ok Mon Jul 2 09:15:58 2012 : Info: [eap] EAP packet type response id 7 length 67 Mon Jul 2 09:15:58 2012 : Info: [eap] No EAP Start, assuming it's an on-going EAP conversation Mon Jul 2 09:15:58 2012 : Info: ++[eap] returns updated Mon Jul 2 09:15:58 2012 : Info: [files] users: Matched entry testtest at line 1 Mon Jul 2 09:15:58 2012 : Info: ++[files] returns ok Mon Jul 2 09:15:58 2012 : Info: ++[smbpasswd] returns notfound Mon Jul 2 09:15:58 2012 : Info: ++[expiration] returns noop Mon Jul 2 09:15:58 2012 : Info: ++[logintime] returns noop Mon Jul 2 09:15:58 2012 : Info: [pap] WARNING: Auth-Type already set. Not setting to PAP Mon Jul 2 09:15:58 2012 : Info: ++[pap] returns noop Mon Jul 2 09:15:58 2012 : Info: Found Auth-Type = EAP Mon Jul 2 09:15:58 2012 : Info: # Executing group from file /etc/freeradius/sites-enabled/inner-tunnel Mon Jul 2 09:15:58 2012 : Info: +- entering group authenticate {...} Mon Jul 2 09:15:58 2012 : Info: [eap] Request found, released from the list Mon Jul 2 09:15:58 2012 : Info: [eap] EAP/mschapv2 Mon Jul 2 09:15:58 2012 : Info: [eap] processing type mschapv2 Mon Jul 2 09:15:58 2012 : Info: [mschapv2] # Executing group from file /etc/freeradius/sites-enabled/inner-tunnel Mon Jul 2 09:15:58 2012 : Info: [mschapv2] +- entering group MS-CHAP {...} Mon Jul 2 09:15:58 2012 : Info: [mschap] Creating challenge hash with username: testtest Mon Jul 2 09:15:58 2012 : Info: [mschap] Told to do MS-CHAPv2 for testtest with NT-Password Mon Jul 2 09:15:58 2012 : Info: [mschap] expand: --username=%{mschap:User-Name:-None} -> --username=testtest Mon Jul 2 09:15:58 2012 : Info: [mschap] No NT-Domain was found in the User-Name. Mon Jul 2 09:15:58 2012 : Info: [mschap] expand: %{mschap:NT-Domain} -> Mon Jul 2 09:15:58 2012 : Info: [mschap] ... expanding second conditional Mon Jul 2 09:15:58 2012 : Info: [mschap] expand: --domain=%{%{mschap:NT-Domain}:-AD.CXO.NAME} -> --domain=AD.CXO.NAME Mon Jul 2 09:15:58 2012 : Info: [mschap] mschap2: 82 Mon Jul 2 09:15:58 2012 : Info: [mschap] Creating challenge hash with username: testtest Mon Jul 2 09:15:58 2012 : Info: [mschap] expand: --challenge=%{mschap:Challenge:-00} -> --challenge=dd441972f987d68b Mon Jul 2 09:15:58 2012 : Info: [mschap] expand: --nt-response=%{mschap:NT-Response:-00} -> --nt-response=7e6c537cd5c26093789cf7831715d378e16ea3e6c5b1f579 Mon Jul 2 09:15:58 2012 : Debug: Exec-Program output: Logon failure (0xc000006d) Mon Jul 2 09:15:58 2012 : Debug: Exec-Program-Wait: plaintext: Logon failure (0xc000006d) Mon Jul 2 09:15:58 2012 : Debug: Exec-Program: returned: 1 Mon Jul 2 09:15:58 2012 : Info: [mschap] External script failed. Mon Jul 2 09:15:58 2012 : Info: [mschap] FAILED: MS-CHAP2-Response is incorrect Mon Jul 2 09:15:58 2012 : Info: ++[mschap] returns reject Mon Jul 2 09:15:58 2012 : Info: [eap] Freeing handler Mon Jul 2 09:15:58 2012 : Info: ++[eap] returns reject Mon Jul 2 09:15:58 2012 : Info: Failed to authenticate the user. Mon Jul 2 09:15:58 2012 : Auth: Login incorrect (mschap: External script says Logon failure (0xc000006d)): [testtest] (from client techap01 port 0 via TLS tunnel) PPS: Maybe the problem is located here: In /etc/freeradius/modules/ntlm_auth I have set ntlm to: program = "/usr/bin/ntlm_auth --request-nt-key --domain=AD.CXO.NAME --username=%{mschap:User-Name} --password=%{User-Password}" I need this, so users can login without adding @ad.cxo.name to their usernames. But how can I tell freeradius to try both logins, [email protected] (should fail) testtest (against users file - should work)

    Read the article

  • c#: exporting swf object as image to Word

    - by Lynn
    Hello in my Asp.net web page (C# on backend) I use a Repeater, whose items consist of a title and a Flex chart (embedded .swf file). I am trying to export the contents of the Repeater to a Word document. My problem is to convert the SWF files into images and pass it on to the Word document. The swf object has a public function which returns a byteArray representation of itself (public function grabScreen():ByteArray), but I do not know how to call it directly from c#. I have access to the mxml files, so I can make modifications to the swf files, if needed. The code is shown below, and your help is appreciated :) .aspx <asp:Button ID="Button1" runat="server" text="export to Word" onclick="print2"/> <asp:Repeater ID="rptrQuestions" runat="server" OnItemDataBound="rptrQuestions_ItemDataBound" > ... <ItemTemplate> <tr> <td> <div align="center"> <asp:Label class="text" Text='<%#DataBinder.Eval(Container.DataItem, "Question_title")%>' runat="server" ID="lbl_title" NAME="lbl_title"/> <br> </div> </td> </tr> <tr><td> <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="result_survey" width="100%" height="100%" codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab"> <param name="movie" value="result_survey.swf" /> <param name="quality" value="high" /> <param name="bgcolor" value="#ffffff" /> <param name="allowScriptAccess" value="sameDomain" /> <param name="flashvars" value='<%#DataBinder.Eval(Container.DataItem, "rank_order")%>' /> <embed src="result_survey.swf?rankOrder='<%#DataBinder.Eval(Container.DataItem, "rank_order")%>' quality="high" bgcolor="#ffffff" width="100%" height="100%" name="result_survey" align="middle" play="true" loop="false" allowscriptaccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer"> </embed> </object> </td></tr> </ItemTemplate> </asp:Repeater> c# protected void print2(object sender, EventArgs e) { HttpContext.Current.Response.Clear(); HttpContext.Current.Response.Charset = ""; HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF7; HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache); HttpContext.Current.Response.ContentType = "application/msword"; HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=" + "Report.doc"); EnableViewState = false; System.IO.StringWriter sw = new System.IO.StringWriter(); HtmlTextWriter htw = new HtmlTextWriter(sw); // Here I render the Repeater foreach (RepeaterItem row in rptrQuestions.Items) { row.RenderControl(htw); } StringBuilder sb1 = new StringBuilder(); sb1 = sb1.Append("<table>" + sw.ToString() + "</table>"); HttpContext.Current.Response.Write(sb1.ToString()); HttpContext.Current.Response.Flush(); HttpContext.Current.Response.End(); } .mxml //################################################## // grabScreen (return image representation of the SWF movie (snapshot) //###################################################### public function grabScreen() : ByteArray { return ImageSnapshot.captureImage( boxMain, 0, new PNGEncoder() ).data(); }

    Read the article

  • iphone app: delegate not responding

    - by Fiona
    Hi guys.. So i'm very new to this iphone development stuff.... and i'm stuck. I'm building an app that connects to the twitter api. However when the connectionDidFinishLoading method gets called, it doesn't seem to recognise the delegate. Here's the source code of the request class: import "OnePageRequest.h" @implementation OnePageRequest @synthesize username; @synthesize password; @synthesize receivedData; @synthesize delegate; @synthesize callback; @synthesize errorCallBack; @synthesize contactsArray; -(void)friends_timeline:(id)requestDelegate requestSelector:(SEL)requestSelector{ //set the delegate and selector self.delegate = requestDelegate; self.callback = requestSelector; //Set up the URL of the request to send to twitter!! NSURL *url = [NSURL URLWithString:@"http://twitter.com/statuses/friends_timeline.xml"]; [self request:url]; } -(void)request:(NSURL *) url{ theRequest = [[NSMutableURLRequest alloc] initWithURL:url]; theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self]; if (theConnection){ //Create the MSMutableData that will hold the received data. //receivedData is declared as a method instance elsewhere receivedData=[[NSMutableData data] retain]; }else{ //errorMessage.text = @"Error connecting to twitter!!"; } } -(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge{ if ([challenge previousFailureCount] == 0){ NSLog(@"username: %@ ",[self username]); NSLog(@"password: %@ ",[self password]); NSURLCredential *newCredential = [NSURLCredential credentialWithUser:[self username] password:[self password] persistence:NSURLCredentialPersistenceNone]; [[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge]; } else { [[challenge sender] cancelAuthenticationChallenge:challenge]; NSLog(@"Invalid Username or password!"); } } -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ [receivedData setLength:0]; } -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ [receivedData appendData:data]; } -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{ [theConnection release]; [receivedData release]; [theRequest release]; NSLog(@"Connection failed. Error: %@ %@", [error localizedDescription], [[error userInfo] objectForKey:NSErrorFailingURLStringKey]); if(errorCallBack){ [delegate performSelector:errorCallBack withObject:error]; } } -(void)connectionDidFinishLoading:(NSURLConnection *)connection{ if (delegate && callback){ if([delegate respondsToSelector:[self callback]]){ [delegate performSelector:[self callback] withObject:receivedData]; }else{ NSLog(@"No response from delegate!"); } } [theConnection release]; [theRequest release]; [receivedData release]; } Here's the .h: @interface OnePageRequest : NSObject { NSString *username; NSString *password; NSMutableData *receivedData; NSURLRequest *theRequest; NSURLConnection *theConnection; id delegate; SEL callback; SEL errorCallBack; NSMutableArray *contactsArray; } @property (nonatomic,retain) NSString *username; @property (nonatomic,retain) NSString *password; @property (nonatomic,retain) NSMutableData *receivedData; @property (nonatomic,retain) id delegate; @property (nonatomic) SEL callback; @property (nonatomic) SEL errorCallBack; @property (nonatomic,retain) NSMutableArray *contactsArray; -(void)friends_timeline:(id)requestDelegate requestSelector:(SEL)requestSelector; -(void)request:(NSURL *) url; @end In the method: connectionDidFinishLoading, the following never gets executed: [delegate performSelector:[self callback] withObject:receivedData]; Instead I get the message: "No response from delegate" Anyone see what I'm doing wrong?! or what might be causing the problem? Regards, Fiona

    Read the article

  • Jquery ajax function working in IE but not in FF

    - by booota
    Okay I have this ajax call $('.updatecom .registercomplaint').click(function(){ updatecomplaints(); }); This calls the function updatecomplaints() function updatecomplaints() { var tno = $(".updatecom #tno").val(); var status = $(".updatecom #status").val(); if(status=='DONE') { $(".updatecom #con").val(''); } var tname = $(".updatecom #tname").val(); var rg11 = $(".updatecom #crg11").val(); var rg06 = $(".updatecom #crg06").val(); var tvpins = $(".updatecom #tvpins").val(); var jointer = $(".updatecom #jointer").val(); var cquantity = $(".updatecom #conqty").val(); var nooftv = $(".updatecom #tvno").val(); var misc = $(".updatecom #misc").val(); var tcomments = $(".updatecom #tcomments").val(); var con = $(".updatecom #con").val(); //alert(tno+status+tname+rg11+rg06+tvpins+jointer+cquantity+nooftv+misc+tcomments+con); $.ajax( { type: "POST", url: "up_functions.php", data: "ticket="+ tno +"& opt=upcom" +"& status="+ status +"& tname="+ tname +"& rg11="+ rg11 +"& rg06="+ rg06 +"& tvpins="+ tvpins +"& jointer="+ jointer +"& cquantity="+ cquantity +"& nooftv="+ nooftv +"& misc="+ misc +"& tcomments="+ tcomments +"& con="+ con, success: function(response) { alert(response); } }); } here is my up_functions.php $tno = htmlspecialchars(trim($_REQUEST['ticket'])); $status = htmlspecialchars(trim($_REQUEST['status'])); $tname = htmlspecialchars(trim($_REQUEST['tname'])); $rg11 = htmlspecialchars(trim($_REQUEST['rg11'])); $rg06 = htmlspecialchars(trim($_REQUEST['rg06'])); $tvpins = htmlspecialchars(trim($_REQUEST['tvpins'])); $jointer = htmlspecialchars(trim($_REQUEST['jointer'])); $cquantity = htmlspecialchars(trim($_REQUEST['cquantity'])); $nooftv = htmlspecialchars(trim($_REQUEST['nooftv'])); $misc = htmlspecialchars(trim($_REQUEST['misc'])); $tcomments = htmlspecialchars(trim($_REQUEST['tcomments'])); $con = htmlspecialchars(trim($_REQUEST['con'])); $result=$ptr->upcomticketinfo($tno,$status,$tname,$rg11,$rg06,$tvpins,$jointer,$cquantity,$nooftv,$misc,$tcomments,$con); echo $result; and here is my upconticketinfo() php function function upcomticketinfo($tno,$status,$tname,$rg11,$rg06,$tvpins,$jointer,$cquantity,$nooftv,$misc,$tcomments,$con) { if($con!='' || $con!=NULL) { $this->query = "update `booking discription` set `STATUS`='$status',`CLOSED ON`='$con' where `TICKET NO`='$tno'"; $this->q_result = mysql_query($this->query,$this->conn) or die(mysql_error()); if($this->q_result) { $query = "update `tech detail` set `TECH NAME`='$tname',`CABLE RG11`='$rg11',`CABLE RG06`='$rg06',`TV PINS USED`='$tvpins',`JOINTER USED`='$jointer',`CONNECTOR QTY`='$cquantity',`NO OF TV`='$nooftv',`MISC`='$misc',`TECH COMMENTS`='$tcomments' where `BOOKING`='$tno'"; $q_result = mysql_query($query,$this->conn) or die(mysql_error()); if($q_result) { $response = "updated"; } else { $response = "error"; } } else { $response = "error"; } } else { $this->query = "update `booking discription` set `STATUS`='$status' where `TICKET NO`='$tno'"; $this->q_result = mysql_query($this->query,$this->conn) or die(mysql_error()); if($this->q_result) { $query = "update `tech detail` set `TECH NAME`='$tname',`CABLE RG11`='$rg11',`CABLE RG06`='$rg06',`TV PINS USED`='$tvpins',`JOINTER USED`='$jointer',`CONNECTOR QTY`='$cquantity',`NO OF TV`='$nooftv',`MISC`='$misc',`TECH COMMENTS`='$tcomments' where `BOOKING`='$tno'"; $q_result = mysql_query($query,$this->conn) or die(mysql_error()); if($q_result) { $response = "updated"; } else { $response = "error"; } } else { $response = "error"; } } return $response; } Question is that, this code is working just fine in IE8 i.e i am using... but it is not working in FF 3.6.3... I have checked each n everything... One thing is that the code works fine on FF too only when i activate the firebug debugger. Otherwise the alert in ajax success shows itself with nothing in it... Help me...

    Read the article

  • Still cant find a solution... about ajax call

    - by booota
    Okay I have this ajax call $('.updatecom .registercomplaint').click(function(){ updatecomplaints(); }); This calls the function updatecomplaints() function updatecomplaints() { var tno = $(".updatecom #tno").val(); var status = $(".updatecom #status").val(); if(status=='DONE') { $(".updatecom #con").val(''); } var tname = $(".updatecom #tname").val(); var rg11 = $(".updatecom #crg11").val(); var rg06 = $(".updatecom #crg06").val(); var tvpins = $(".updatecom #tvpins").val(); var jointer = $(".updatecom #jointer").val(); var cquantity = $(".updatecom #conqty").val(); var nooftv = $(".updatecom #tvno").val(); var misc = $(".updatecom #misc").val(); var tcomments = $(".updatecom #tcomments").val(); var con = $(".updatecom #con").val(); //alert(tno+status+tname+rg11+rg06+tvpins+jointer+cquantity+nooftv+misc+tcomments+con); $.ajax( { type: "POST", url: "up_functions.php", data: "ticket="+ tno +"& opt=upcom" +"& status="+ status +"& tname="+ tname +"& rg11="+ rg11 +"& rg06="+ rg06 +"& tvpins="+ tvpins +"& jointer="+ jointer +"& cquantity="+ cquantity +"& nooftv="+ nooftv +"& misc="+ misc +"& tcomments="+ tcomments +"& con="+ con, success: function(response) { alert(response); } }); } here is my up_functions.php $tno = htmlspecialchars(trim($_REQUEST['ticket'])); $status = htmlspecialchars(trim($_REQUEST['status'])); $tname = htmlspecialchars(trim($_REQUEST['tname'])); $rg11 = htmlspecialchars(trim($_REQUEST['rg11'])); $rg06 = htmlspecialchars(trim($_REQUEST['rg06'])); $tvpins = htmlspecialchars(trim($_REQUEST['tvpins'])); $jointer = htmlspecialchars(trim($_REQUEST['jointer'])); $cquantity = htmlspecialchars(trim($_REQUEST['cquantity'])); $nooftv = htmlspecialchars(trim($_REQUEST['nooftv'])); $misc = htmlspecialchars(trim($_REQUEST['misc'])); $tcomments = htmlspecialchars(trim($_REQUEST['tcomments'])); $con = htmlspecialchars(trim($_REQUEST['con'])); $result=$ptr->upcomticketinfo($tno,$status,$tname,$rg11,$rg06,$tvpins,$jointer,$cquantity,$nooftv,$misc,$tcomments,$con); echo $result; and here is my upconticketinfo() php function function upcomticketinfo($tno,$status,$tname,$rg11,$rg06,$tvpins,$jointer,$cquantity,$nooftv,$misc,$tcomments,$con) { if($con!='' || $con!=NULL) { $this->query = "update `booking discription` set `STATUS`='$status',`CLOSED ON`='$con' where `TICKET NO`='$tno'"; $this->q_result = mysql_query($this->query,$this->conn) or die(mysql_error()); if($this->q_result) { $query = "update `tech detail` set `TECH NAME`='$tname',`CABLE RG11`='$rg11',`CABLE RG06`='$rg06',`TV PINS USED`='$tvpins',`JOINTER USED`='$jointer',`CONNECTOR QTY`='$cquantity',`NO OF TV`='$nooftv',`MISC`='$misc',`TECH COMMENTS`='$tcomments' where `BOOKING`='$tno'"; $q_result = mysql_query($query,$this->conn) or die(mysql_error()); if($q_result) { $response = "updated"; } else { $response = "error"; } } else { $response = "error"; } } else { $this->query = "update `booking discription` set `STATUS`='$status' where `TICKET NO`='$tno'"; $this->q_result = mysql_query($this->query,$this->conn) or die(mysql_error()); if($this->q_result) { $query = "update `tech detail` set `TECH NAME`='$tname',`CABLE RG11`='$rg11',`CABLE RG06`='$rg06',`TV PINS USED`='$tvpins',`JOINTER USED`='$jointer',`CONNECTOR QTY`='$cquantity',`NO OF TV`='$nooftv',`MISC`='$misc',`TECH COMMENTS`='$tcomments' where `BOOKING`='$tno'"; $q_result = mysql_query($query,$this->conn) or die(mysql_error()); if($q_result) { $response = "updated"; } else { $response = "error"; } } else { $response = "error"; } } return $response; } Question is that, this code is working just fine in IE8 i.e i am using... but it is not working in FF 3.6.3... I have checked each n everything... One thing is that the code works fine on FF too only when i debug the page with firebug debugger. Otherwise the alert in ajax success shows itself with nothing in it... Help me...

    Read the article

  • Adding an Admin user to an ASP.NET MVC 4 application using a single drop-in file

    - by Jon Galloway
    I'm working on an ASP.NET MVC 4 tutorial and wanted to set it up so just dropping a file in App_Start would create a user named "Owner" and assign them to the "Administrator" role (more explanation at the end if you're interested). There are reasons why this wouldn't fit into most application scenarios: It's not efficient, as it checks for (and creates, if necessary) the user every time the app starts up The username, password, and role name are hardcoded in the app (although they could be pulled from config) Automatically creating an administrative account in code (without user interaction) could lead to obvious security issues if the user isn't informed However, with some modifications it might be more broadly useful - e.g. creating a test user with limited privileges, ensuring a required account isn't accidentally deleted, or - as in my case - setting up an account for demonstration or tutorial purposes. Challenge #1: Running on startup without requiring the user to install or configure anything I wanted to see if this could be done just by having the user drop a file into the App_Start folder and go. No copying code into Global.asax.cs, no installing addition NuGet packages, etc. That may not be the best approach - perhaps a NuGet package with a dependency on WebActivator would be better - but I wanted to see if this was possible and see if it offered the best experience. Fortunately ASP.NET 4 and later provide a PreApplicationStartMethod attribute which allows you to register a method which will run when the application starts up. You drop this attribute in your application and give it two parameters: a method name and the type that contains it. I created a static class named PreApplicationTasks with a static method named, then dropped this attribute in it: [assembly: PreApplicationStartMethod(typeof(PreApplicationTasks), "Initializer")] That's it. One small gotcha: the namespace can be a problem with assembly attributes. I decided my class didn't need a namespace. Challenge #2: Only one PreApplicationStartMethod per assembly In .NET 4, the PreApplicationStartMethod is marked as AllMultiple=false, so you can only have one PreApplicationStartMethod per assembly. This was fixed in .NET 4.5, as noted by Jon Skeet, so you can have as many PreApplicationStartMethods as you want (allowing you to keep your users waiting for the application to start indefinitely!). The WebActivator NuGet package solves the multiple instance problem if you're in .NET 4 - it registers as a PreApplicationStartMethod, then calls any methods you've indicated using [assembly: WebActivator.PreApplicationStartMethod(type, method)]. David Ebbo blogged about that here:  Light up your NuGets with startup code and WebActivator. In my scenario (bootstrapping a beginner level tutorial) I decided not to worry about this and stick with PreApplicationStartMethod. Challenge #3: PreApplicationStartMethod kicks in before configuration has been read This is by design, as Phil explains. It allows you to make changes that need to happen very early in the pipeline, well before Application_Start. That's fine in some cases, but it caused me problems when trying to add users, since the Membership Provider configuration hadn't yet been read - I got an exception stating that "Default Membership Provider could not be found." The solution here is to run code that requires configuration in a PostApplicationStart method. But how to do that? Challenge #4: Getting PostApplicationStartMethod without requiring WebActivator The WebActivator NuGet package, among other things, provides a PostApplicationStartMethod attribute. That's generally how I'd recommend running code that needs to happen after Application_Start: [assembly: WebActivator.PostApplicationStartMethod(typeof(TestLibrary.MyStartupCode), "CallMeAfterAppStart")] This works well, but I wanted to see if this would be possible without WebActivator. Hmm. Well, wait a minute - WebActivator works in .NET 4, so clearly it's registering and calling PostApplicationStartup tasks somehow. Off to the source code! Sure enough, there's even a handy comment in ActivationManager.cs which shows where PostApplicationStartup tasks are being registered: public static void Run() { if (!_hasInited) { RunPreStartMethods(); // Register our module to handle any Post Start methods. But outside of ASP.NET, just run them now if (HostingEnvironment.IsHosted) { Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(StartMethodCallingModule)); } else { RunPostStartMethods(); } _hasInited = true; } } Excellent. Hey, that DynamicModuleUtility seems familiar... Sure enough, K. Scott Allen mentioned it on his blog last year. This is really slick - a PreApplicationStartMethod can register a new HttpModule in code. Modules are run right after application startup, so that's a perfect time to do any startup stuff that requires configuration to be read. As K. Scott says, it's this easy: using System; using System.Web; using Microsoft.Web.Infrastructure.DynamicModuleHelper; [assembly:PreApplicationStartMethod(typeof(MyAppStart), "Start")] public class CoolModule : IHttpModule { // implementation not important // imagine something cool here } public static class MyAppStart { public static void Start() { DynamicModuleUtility.RegisterModule(typeof(CoolModule)); } } Challenge #5: Cooperating with SimpleMembership The ASP.NET MVC Internet template includes SimpleMembership. SimpleMembership is a big improvement over traditional ASP.NET Membership. For one thing, rather than forcing a database schema, it can work with your database schema. In the MVC 4 Internet template case, it uses Entity Framework Code First to define the user model. SimpleMembership bootstrap includes a call to InitializeDatabaseConnection, and I want to play nice with that. There's a new [InitializeSimpleMembership] attribute on the AccountController, which calls \Filters\InitializeSimpleMembershipAttribute.cs::OnActionExecuting(). That comment in that method that says "Ensure ASP.NET Simple Membership is initialized only once per app start" which sounds like good advice. I figured the best thing would be to call that directly: new Mvc4SampleApplication.Filters.InitializeSimpleMembershipAttribute().OnActionExecuting(null); I'm not 100% happy with this - in fact, it's my least favorite part of this solution. There are two problems - first, directly calling a method on a filter, while legal, seems odd. Worse, though, the Filter lives in the application's namespace, which means that this code no longer works well as a generic drop-in. The simplest workaround would be to duplicate the relevant SimpleMembership initialization code into my startup code, but I'd rather not. I'm interested in your suggestions here. Challenge #6: Module Init methods are called more than once When debugging, I noticed (and remembered) that the Init method may be called more than once per page request - it's run once per instance in the app pool, and an individual page request can cause multiple resource requests to the server. While SimpleMembership does have internal checks to prevent duplicate user or role entries, I'd rather not cause or handle those exceptions. So here's the standard single-use lock in the Module's init method: void IHttpModule.Init(HttpApplication context) { lock (lockObject) { if (!initialized) { //Do stuff } initialized = true; } } Putting it all together With all of that out of the way, here's the code I came up with: using Mvc4SampleApplication.Filters; using System.Web; using System.Web.Security; using WebMatrix.WebData; [assembly: PreApplicationStartMethod(typeof(PreApplicationTasks), "Initializer")] public static class PreApplicationTasks { public static void Initializer() { Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility .RegisterModule(typeof(UserInitializationModule)); } } public class UserInitializationModule : IHttpModule { private static bool initialized; private static object lockObject = new object(); private const string _username = "Owner"; private const string _password = "p@ssword123"; private const string _role = "Administrator"; void IHttpModule.Init(HttpApplication context) { lock (lockObject) { if (!initialized) { new InitializeSimpleMembershipAttribute().OnActionExecuting(null); if (!WebSecurity.UserExists(_username)) WebSecurity.CreateUserAndAccount(_username, _password); if (!Roles.RoleExists(_role)) Roles.CreateRole(_role); if (!Roles.IsUserInRole(_username, _role)) Roles.AddUserToRole(_username, _role); } initialized = true; } } void IHttpModule.Dispose() { } } The Verdict: Is this a good thing? Maybe. I think you'll agree that the journey was undoubtedly worthwhile, as it took us through some of the finer points of hooking into application startup, integrating with membership, and understanding why the WebActivator NuGet package is so useful Will I use this in the tutorial? I'm leaning towards no - I think a NuGet package with a dependency on WebActivator might work better: It's a little more clear what's going on Installing a NuGet package might be a little less error prone than copying a file A novice user could uninstall the package when complete It's a good introduction to NuGet, which is a good thing for beginners to see This code either requires either duplicating a little code from that filter or modifying the file to use the namespace Honestly I'm undecided at this point, but I'm glad that I can weigh the options. If you're interested: Why are you doing this? I'm updating the MVC Music Store tutorial to ASP.NET MVC 4, taking advantage of a lot of new ASP.NET MVC 4 features and trying to simplify areas that are giving people trouble. One change that addresses both needs us using the new OAuth support for membership as much as possible - it's a great new feature from an application perspective, and we get a fair amount of beginners struggling with setting up membership on a variety of database and development setups, which is a distraction from the focus of the tutorial - learning ASP.NET MVC. Side note: Thanks to some great help from Rick Anderson, we had a draft of the tutorial that was looking pretty good earlier this summer, but there were enough changes in ASP.NET MVC 4 all the way up to RTM that there's still some work to be done. It's high priority and should be out very soon. The one issue I ran into with OAuth is that we still need an Administrative user who can edit the store's inventory. I thought about a number of solutions for that - making the first user to register the admin, or the first user to use the username "Administrator" is assigned to the Administrator role - but they both ended up requiring extra code; also, I worried that people would use that code without understanding it or thinking about whether it was a good fit.

    Read the article

< Previous Page | 54 55 56 57 58 59 60 61 62 63 64 65  | Next Page >