Trying to Make the Simplest OpenID using DotNetOpenAuth Login in asp.net - dotnetopenauth

I've downloaded the Visual Studio 2010 Template associated with the http://www.dotnetopenauth.net/. I can get that to work as advertised. I am not starting a project from scratch and I don't want to put a lot of time into integrating all the web.config, handlers, etc. into my application to get OpenID working for me. The doc says that I should be able to make a one line implementation using a button and a user control. I believe I have done that and I get an error.
Here is what I've done.
Create empty asp.net web project
Add DotNetOpenAuth.dll to bin and reference it
Add user control registration to top of page
Create Button on page that calls user control.
When I run it and press the button, I get:
"Precondition failed: this.Identifier != null No identifier has been set."
I know there must be more to it than this, but I just don't get it. Can someone explain further what I need to do?
Thanks,
<%# Page Language="C#" %>
<%# Register Assembly="DotNetOpenAuth" Namespace="DotNetOpenAuth.OpenId.RelyingParty" TagPrefix="rp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void LoginId_Click(object sender, EventArgs e)
{
OpenIdTextBox1.LogOn();
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="LoginId" runat="server" Text="Button" onclick="LoginId_Click" />
<rp:OpenIdTextBox ID="OpenIdTextBox1" runat="server" />
</div>
</form>
</body>
</html>

You you actually typing an identifier in the box before clicking the button? You must.
And you can avoid the nasty error for people who forget to type an identifier by adding a RequiredFieldValidator control that points to the text box and then checking that if (Page.IsValid) in your button's click handler before calling LogOn.
Hopefully this helps. Have you considered using the OpenIdLogin control? If you're shooting for easiest to add, that's the easiest, as you don't have any code at all -- just the one tag.
Also, be sure to add ValidateRequest="false" to your <%# Page %> tag at the top of your login page. Otherwise your users will see occasional random failures because ASP.NET incorrectly interprets some OpenID authentication responses to be attacks.
So for example, if the top line of your .aspx was:
<%# Page Language="C#" AutoEventWireup="True" CodeBehind="login.aspx.cs" Inherits="OpenIdRelyingPartyWebForms.login" %>
Make it
<%# Page ValidateRequest="false" Language="C#" AutoEventWireup="True" CodeBehind="login.aspx.cs" Inherits="OpenIdRelyingPartyWebForms.login" %>

Related

How to change url and avoid refreshing the whole page when an hyperlink is clicked from the SSRS Report

My question is, is there a way to change the url without refreshing the whole web page when an hyperlink from the SSRS Report is clicked?
I tried 2 different implementations of hyperlink in SSRS Report RDLC which are indicated here:
SSRS: How to display a hyperlink in sql services reporting
1st Way
Textbox Properties > Action pane > Go to URL radio button > Selected URL: http:// localhost:(port)/#/Path/ViewDetails
2nd Way
Create Placeholder > Right click > Placeholder Properties > General Pane > On Markup type: HTML - Interpret HTML tags at styles > Value: ="< a href="http:// localhost:(port)/#/Path/ViewDetails">View Details< /a>"
I have an MVC project that uses AngularJS and has implemented local processing mode of SSRS Report Viewer. The Report Viewer was implemented in an ASPX page (MVC.ViewPage)
ReportViewer.aspx
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<SampleProject.Models.ReportInfo>" %>
<%# Register Assembly="Microsoft.ReportViewer.WebForms, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" Namespace="Microsoft.Reporting.WebForms" TagPrefix="rsweb" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="scriptManager" runat="server" ScriptMode="Release"></asp:ScriptManager>
<rsweb:ReportViewer ID="ReportViewer" runat="server"
SizeToReportContent="true" AsyncRendering="false" Visible="true"
ProcessingMode="Local" EnableViewState="true"
InternalBorderStyle="None" BorderStyle="None" InternalBorderWidth="0"
KeepSessionAlive="false" >
</rsweb:ReportViewer>
</form>
<script runat="server">
override protected void OnInit(EventArgs e){
// some report viewer initialization here
// some datasource data population code here
}
</script>
I put load this ASPX page into an IFrame of an MVC Partial View.
ViewDetail.cshtml
<div>
<iframe src="{{report.viewDetailPath}}"></iframe>
</div>
viewDetail.js (AngularJS Controller)
angular.module('project').controller("ViewDetailCtrl", function($scope){
$scope.report = {
id: // some guid,
viewDetailPath: '/Reports/ReportViewer';
}
}
I have a RDLC report with an hyperlink "View Detail".
I want my app to behave like a Single Page Application. When I click the "View Detail" link from the report, instead of refreshing the whole page, it will only change the URL and execute a javascript method from the AngularJS controller.
I have also implemented a $routeProvider of AngularJS in order to look like a single page application.
app.js
project.config(function($routeProvider){
$routeProvider.
when('/', {template: 'NYI'}).
when('/Path/ViewDetails', {controller: 'ViewDetailCtrl', templateUrl: '/Reports/ViewDetail'}).
otherwise({redirectTo: '/'});
});
ReportsController.cs(MVC Controller)
public PartialViewResult ViewDetail(){
return PartialView("~/Views/Reports/ViewDetail.cshtml");
}
public ActionResult ReportViewer(){
return View("~/Views/Reports/ReportViewer.aspx", new ReportInfo());
}
The $routeProvider to make the application like a single page app, does not work when the SSRS Report hyperlink changed the URL.
You will need to attach a "onclick" event handler to the links in question. This onclick handler can then prevent the click but instead change the URL by e.g. using angular's $location.update function (or setting $window.location.href in newer versions).
Here is angular's documentation on how to manipulate the URL: http://docs.angularjs.org/guide/dev_guide.services.$location
And here is a very simple example of such an event handler and how to attach it to a link. You might have to use something like getElementsByClassname instead (with a loop) or even some complicated selector:
function linkclick(e) {
alert(e.target);
e.preventDefault();
}
document.getElementById('testid').onclick = linkclick;
See it working here. It will just alert the URL clicked, but prevent the browser from opening that URL: http://jsfiddle.net/eJBfn/
If you're talking about deep linking in angular you need to use #/ before all of your anchor tag hrefs:

How to change remoteurl of jquery struts2 dialog(remote)?

I am using struts2-jquery plugin & using dialog(remote) so i have specified remoteurl before dialog code as shown below:
<%# taglib prefix="s" uri="/struts-tags"%>
<%# taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head jqueryui="true"/>
</head>
<body>
<s:url var="remoteurl" action="myremoteaction"/>
<sj:dialog id="mydialog3" href="%{remoteurl}" title="Remote Dialog open on Click" autoOpen="false"/>
<sj:a openDialog="mydialog3">Open Dialog</sj:a>
</body>
</html>
When i click on hyperlink instead of opening dialog directly first i want to change its remoteurl & then want to open it
Can somebody tell me how should i do this?
Thanks in advance.
You can try this. I've not tested it but i believe it will give you a clue on how to solve the problem. Change the value of the href attribute before opening the dialog using something like this:
$("#mydialog3").dialog( "option" , "href", your_new_url );
$("#mydialog3").dialog('open')
You can also visit the Struts2 jquery showcase page for more clarification.

How to update counter without sending request to server

I m building a website where i need to update project counter whenever its updated in DB. when ever any user add a new project, the project counter should automatically update in browser, but i don't want to send ajax request to server again and again to get count from DB and then update counter in web browser.
I want something similar "how facebook notification updated" automatically without refreshing page or sending any ajax request, i know there are using some PUSH technology but i not sure how it works.
It will be very great if someone provide some Example code to achieve this.
Thanks...
Have you considered using SignalR?
http://www.hanselman.com/blog/AsynchronousScalableWebApplicationsWithRealtimePersistentLongrunningConnectionsWithSignalR.aspx
http://signalr.net/
Here is the sample code based on a quick POC after reading some SO replies and above articles. Hope it helps.
Create a new empty ASP.NET web application project
Add the SignalR package via NuGet
Add a UserCounter.cs with following code. Just need to inherit the class from Hub base class.
using SignalR.Hubs;
public class UserCounter : Hub { }
Add a Default.aspx with following code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
</head>
<body>
<form id="form1" runat="server">
<div>
Number of users currently online - <b><span id="noOfUsers">0</span> users</b>
<br />
<a target="_blank" href="UpdateNoOfUsers.aspx">Change number of users</a>
</div>
</form>
</body>
<script src="Scripts/jquery-1.6.4.js" type="text/javascript"></script>
<script src="Scripts/jquery.signalR.js" type="text/javascript"></script>
<script src="/signalr/hubs" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
var usc = $.connection.userCounter;
usc.noOfUsersUpdated = function (message) {
$('#noOfUsers').text(message);
};
$.connection.hub.start();
});
</script>
</html>
Add a UpdateNoOfUsers.aspx with following code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
</head>
<body>
<form id="form1" runat="server">
<div>
No. of users: <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
</div>
</form>
</body>
</html>
Add an event-handler for button-click for button in UpdateNoOfUsers.aspx
using SignalR;
using SignalR.Infrastructure;
using SignalR.Hosting.AspNet;
protected void Button1_Click(object sender, EventArgs e)
{
IConnectionManager connectionManager = AspNetHost.DependencyResolver.Resolve<IConnectionManager>();
dynamic clients = connectionManager.GetClients<UserCounter>();
clients.noOfUsersUpdated(TextBox1.Text);
}
Run the application after setting "Default.aspx" as the start up page
Click on the "Change number of users" link to open a new browser window
Enter a number in text-box and click on the button to see the value change in base window! Open this page in some other browser and see the same behaviour!

Nerd dinner error on Ajax call to Register action method

I'm new to MVC and I'm implementing the Nerd Dinner MVC sample app in MS MVC2. I'm on step 10, "Ajax enabling RSVPs accepts". I've added the new RSVP controller and added the Register action method like so:
public class RSVPController : Controller
{
DinnerRepository dinnerRepository = new DinnerRepository();
//
// AJAX: /Dinners/RSVPForEvent/1
[Authorize, AcceptVerbs(HttpVerbs.Post)]
public ActionResult Register(int id) {
Dinner dinner = dinnerRepository.GetDinner(id);
if (!dinner.IsUserRegistered(User.Identity.Name)) {
RSVP rsvp = new RSVP();
rsvp.AttendeeName = User.Identity.Name;
dinner.RSVPs.Add(rsvp);
dinnerRepository.Save();
}
return Content("Thanks - we'll see you there!");
}
}
I added the references to both Ajax script libraries and added the code below to the Details view as described in the article:
<div id="rsvpmsg">
<% if(Request.IsAuthenticated) { %>
<% if(Model.IsUserRegistered(Context.User.Identity.Name)) { %>
<p>You are registred for this event!</p>
<% } else { %>
<%= Ajax.ActionLink( "RSVP for this event",
"Register", "RSVP",
new { id=Model.DinnerID },
new AjaxOptions { UpdateTargetId="rsvpmsg"}) %>
<% } %>
<% } else { %>
Logon to RSVP for this event.
<% } %>
</div>
When I click the "RSVP for this event" link I get a 404 eror saying the resource cannot be found:
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /NerdDinner/RSVP/Register/24
Version Information: Microsoft .NET Framework Version:2.0.50727.4200; ASP.NET Version:2.0.50727.4205
When I step into the code it is finding the Register action method correctly. After playing around with it I removed the "AcceptVerbs(HttpVerbs.Post)" from the constraint on the Register method, and it then worked. However it didn't reload the page it just displayed the "Thanks - we'll see you there" message on a new blank page. Looking at the html in the details page there is no Form submit taking place, so I'm wondering does the Ajax code need something more to make the call a Post? Is there a known issue with this part of the Nerd Dinner app? I think the app was written in MVC1 and I'm using MVC2 - does this make a diference?
TIA,
Ciaran
The PDF tutorial (versus the online HTML version) has typographic ANSI quote characters (0x94) rather than ASCII (0x22) in the HTML block of script elements. The correct block is shown below with all of the quote characters replaced.
<script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="/Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>
Visual Studio will mark the JavaScript source files with the Warning green squiggles ("File not found") but not the type attributes so you may notice and correct the problem only for the source files. However, the type attributes will still be malformed and this will cause the scripts not to be loaded correctly in the browser.
Using the Chrome developer tools, I noticed that the scripts were not listed as Resources for the Details HTML page. Correcting the quote characters for the type attributes allowed the Register action to work as documented in the tutorial with no changes.
This portion of your action explains why you just get the "see you there" message:
return Content("Thanks - we'll see you there!");
That's all that's being returned.
The reason you were getting a 404 to begin with is the use of an actionlink:
Ajax.ActionLink(...
That will create a URL link, a GET not a POST, and the AcceptVerbs(HttpVerbs.Post) would have forced no match. You should submit a form to do a post:
using (Ajax.BeginForm("Controller", "Action", new AjaxOptions { UpdateTargetId = "f1" } )) { %>
<div id="f1">
<!-- form fields here -->
<input type="submit" />
</div>
<% } %>
As an additional comment to debugging issues with this problem, being a Java/JSF developer, I ran into a hard lesson that
<script src="/Scripts/MicrosoftAjax.js" type="text/javascript" />
and
<script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script>
are processed differently. The first not working at all and the second working correctly.
This is the Details.cshtml used in MVC3. The problem with redirecting using GET, and not POST is similar.
<div id="rsvpmsg">
#if (Request.IsAuthenticated)
{
if (Model.IsUserRegistered(Context.User.Identity.Name))
{
<p>
You are registered for this event</p>
}
else
{
#Ajax.ActionLink("RSVP for this event",
"Register",
"RSVP",
new { id = Model.DinnerID },
new AjaxOptions { UpdateTargetId = "rsvpmsg", HttpMethod = "Post" })
}
}
else
{
<p>
Logon to RSVP for this event.</p>
}
</div>
#section JavaScript
{
<script src="#Url.Content("~/Scripts/MicrosoftAjax.js")" type="text/javascript"></script>;
<script src="#Url.Content("~/Scripts/MicrosoftMvcAjax.js")" type="text/javascript"></script>;
}
Ok, so previously i have mentioned that i had the same problem, and it comes from the fact that MVC 3 uses unobtrusive JavaScript.
To make this work, you have 2 solutions, one is to disable Unobtrusive Javascript in your webconfig file:
<appSettings>
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
Just set it to false, and during page build, javascript generated for the Action link will be normal inline javascript, that works fine, and results with something like this in HTML:
<a onclick="Sys.Mvc.AsyncHyperlink.handleClick(this, new Sys.UI.DomEvent(event),
{ insertionMode: Sys.Mvc.InsertionMode.replace, httpMethod: 'Post', updateTargetId: 'rsvpmsg' });" href="/RSVP/Register/13">RSVP for this event</a>
Second solution is more to my liking and it is just as simple. You just have to include additional javascript source file in your header:
<head>
<title>#ViewBag.Title</title>
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
#RenderSection("JavaScript",required:false)
</head>
The resulting javascript generated is unobtrusive, and results with this in HTML:
RSVP for this event
In both cases the resulting functionality is the same, and the second solution is "more in spirit" of new MVC 3.
Just in case it helps someone else, i had the problem using MVC 3 and it was because I had linked to the MS AJAX libraries and MVC 3 actually uses jQuery by default so I just needed to uncomment the links in my master page and it was fine.
To make an http post with Ajax.ActionLink , you'd have to do e.g. new AjaxOptions { UpdateTargetId="rsvpmsg",HttpMethod="POST"}
if you include those two in your site.master, it should be fine
<script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="/Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>
I was trying to convert to MVC3/Razor as I worked through this example. I've been stuck on this exact same issue for at least 24 hours now...exact same symptoms. I tried everything on this page that I could understand or thought was relevant.
I didn't have the unobtrusive javascript mention in my web.config and was considering adding it with the "false" value thinking "true" might be the default. However, I was thinking it might screw something else up (among who knows what else).
I found the following tid-bit over on the wrox forum. If I add the following line of code to the second line of my RSVPStatus.cshtml partial view:
<script src="/Scripts/jquery.unobtrusive-ajax.min.js" type="text/javascript"></script>
Everything works as intended. I know Zak mentioned that line of code above (and a bunch of other stuff that lead me in the right direction), but I was using the partial view and haven't seen a head tag since I started messing with MVC. I know it's probably there somewhere, but all the smoke and mirrors of what is MS programming now, makes it harder to dissect and I probably would have gone down Zak's path at some point. So, +1 for him.
Anyway, hope this helps someone save a day.

How to get at Header

I'm trying to pass the header object here:
<%=FileUtil.AddStylesheetToHeader(Header, "UsedItems.css") %>
In my Master page I have a <head runat="server">. And my aspx page definitely has a reference to my MasterPageFile in the page directive at the top of my MVC based .aspx.
I also have an import statement the namespace that the FileUtil class resides in :
<%# Import Namespace="xxxx.Web.Utilities" %>
In standard ASP.NET you could reference the header with this.Header but in MVC I'm not able to do this...or I'm missing some kind of Imports or something.
for some reason though at runtime, with that call to AddStylesheetToHeader, I get the following error:
The best overloaded method match for 'System.IO.TextWriter.Write(char)' has some invalid arguments.
I'm not sure why it's looking at a .NET type as I know when I mouseover my FileUtil at compile time it's definitely referencing xxxx.Web.Utilities.FileUtil.
In that method I'm using HtmlLink styleSheet = new HtmlLink(); I may not be able to use this as it's an ASP.NET Web control? Here's that method:
public static void AddStylesheetToHeader(HtmlHead header, string cssFilename)
{
HtmlLink styleSheet = new HtmlLink();
styleSheet.Href = "content/css/" + cssFilename;
styleSheet.Attributes.Add("rel", "stylesheet");
styleSheet.Attributes.Add("type", "text/css");
header.Controls.Add(styleSheet);
}
I don't think I can use conrols that stem from System.Web.Controls since this is an ASP.NET application? If so, the how can I add a control to the header controls collection? Would I need to do this differently in MVC?
There may be a way to do it the way you're attempting, but it's more common in ASP.NET MVC to create a content placeholder in the <head> rather than accessing it programmatically. For example, your master view could look something like this:
<html>
<head>
<asp:ContentPlaceHolder ID="HeadContent" runat="server" />
</head>
</html>
And your view could look like this:
<asp:Content runat="server" ContentPlaceHolderID="HeadContent">
<link href="/content/css/UsedItems.css" rel="Stylesheet" type="text/css" />
</asp:Content>
have you tried this.Request.Header?
You can use JavaScript to dynamically add content to your HEAD section as shown in the code below:
<script language="javascript" type="text/javascript">
$(document).ready(function() {
$("head").append("<link href='Content/Site.css' rel='stylesheet' type='text/css' />");
});
</script>

Resources