08 April, 2009

Sharepoint Access Exception for elevated privileges

Working with FBA I encountered the most bazaar issue. I want my FBA user that is not Admin to be able to update their profile details both their name and email address. SO this works perfectly well when I want to update the DB but the issue comes when I want to update the SPUser account of that user.

I tried many different solutions, Allowing Anonymous Access on both the web and the site and also impersonating the user. In the end the solution which is not that obvious was to disable the FormDigest. Found in this msdn thread.

Here is my final code solution : Prior to this i make sure that this code only executes when the user is non admin

SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(this.Site.ID))
{

site.AllowUnsafeUpdates = true;
using (SPWeb web = site.OpenWeb())

{
SPWebApplication webApp = web.Site.WebApplication;
bool formDigest = webApp.FormDigestSettings.Enabled;
webApp.FormDigestSettings.Enabled = false;


web.AllowUnsafeUpdates = true;
SPIisSettings usersettings = Utils.GetFBAIisSettings(site);
SPUser spUpdateuser = web.AllUsers[usersettings.MembershipProvider + ":" + userName];
if (spuser != null)
{
spUpdateuser.Email = txtEmail.Text;
spUpdateuser.Name = txtFullName.Text;
spUpdateuser.Update();
}
webApp.FormDigestSettings.Enabled = formDigest;
}
}
}
);

15 January, 2009

jQuery hide unchecked Check Boxes

In my scenario a user can select people to add to a list (using checkboxes). The update is done via jQuery $post so there is no refresh. In order to make it seem more fluent I need to hide all the people that are not checked making it seem as though there was a full update. *a full update happens when the user refreshes the page.

So the solution: use jQuery to hide checkboxes that are not checked.


var divId = "yourDivID";

$("#"+divId+" input:checkbox").not(":checked").each(function(){
$(this).next().hide();
$(this).hide();
});


the text next to the checkbox is inside a span tag. This allows it to be recognised correctly when using .next()

jQuery Check Boxes all Checked Values from Div

Something super awesome with jQuery. The ability to get all the values of checkboxes that are checked within a specific div.

//divid is your unique DIV id
$("#divId input:checked").each(function(){
alert($(this).val());
});

As simple as that! We get all the checked ckeckbxes from divId and then alert each of their values. Just remember to leave a space between the divId and input.
Enjoy

30 November, 2008

Copying an unseekable stream

I came across this issue the other day. I was trying to copy an image from a site into my SharePoint list. The issue was that the Stream that I was receiving was not seekable making it impossible to find out its size. After some awesome google skills and some help from my workmate we came up with a simple solution.

We copy the unseekable stream 64bytes at a time into a new stream making it seekable.

and TADA, this is what you end up with

private static void CopyUnseekableStream(Stream input, Stream output)
{
if (input == null) throw new ArgumentNullException("input");
if (output == null) throw new ArgumentNullException("output");
try
{
using (BinaryWriter bwWriter = new BinaryWriter(output))
using (BinaryReader brReader = new BinaryReader(input))
{
byte[] buf;
do
{
buf = brReader.ReadBytes(1024 * 64); // you can make this any size
bwWriter.Write(buf);
}
while (buf.Length > 0);
bwWriter.Close();
brReader.Close();
}
}
catch (Exception ex)
{

//need to catch errors
}
}
}

17 November, 2008

Virtual Earth Web Part for SharePoint Part 1

We all know that Microsoft have released new live BETA controls for the development community to use. I've been playing around with the Virtual Earth control and trying to get it to work within a Share Point web part.

I started this development using just a plain HTML page to see how the functionality works.
I've had a go at adding the control to the page and add/remove/move/load pins. Pins will be the most important part of your virtual earth. Whether you want to or not, users want to have the ability to plot destinations on the globe. There are many different reasons why a user would want to plot locations. To be honest I don't care why, as to HOW now that's what I want to discover.

We need to start this easy html page by referencing the control and adding the control to the page, and adding the required radio buttons that we will use to determine our users action. This is due to the fact that there is no Right click in web!

I start with a basic html page so that you can work out all the necessities for your JavaScript code. Since you can't really debug the js from your web part you will need to debug it in VS 2008 !

Let's begin.

1. We need to add all the required elements to the page. We need to reference the js control and from Microsoft.

<script type="text/javascript" src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2"></script>

now that we have referenced the controls we need to add all the required elements to the page. I will take you through everything that we are adding.

1. We need to add the Virtual Earth Control:

<div id='myMap' style='position:relative; width:400px; height:300px;'></div>

This will add a blank space to your page. This is where the map will load. Its nothing more than a div with some sizes.

In order to load the map we will need to add a button and we will load the map and some default pins on the button click.

<input id="getMap" type="button" value="Get Map" name="getMap" onclick='GetMap();loadPins();'/>

There are two main methods that we will create.

1.1 GetMap(); this will load up the map
1.2 loadPins(); this will load the default pins.

speaking of load pins, we will add some default pins to this page as follows:


<input type="hidden" id="VEpin_msftve_1000_200001" value="Default Description;-41.28854540914936;174.77679491043088" />

<input type="hidden" id="VEpin_msftve_1000_200002" value="This is pin 2;-41.28519169519274;174.77449893951424" />

<input type="hidden" id="VEpin_msftve_1000_200003" value="this is pin 3;-41.28699756258909;174.77278232574466" />



This hidden input contains some crucial information. The pin description (this will appear in the info box and also the Longitude and Latitude.) Since there is no right click in web we need to add some radio buttons. This will help determine what action the user wants to perform. So we add a radio group.

<input id="addPin" name="pinOptions" type="radio" value ="AddPin">Add Pin</input> <input id="removePin" name="pinOptions" type="radio" value ="RemovePin">Remove Pin</input> <input id="navigate" name="pinOptions" type="radio" value ="navigate" checked ="checked" >Navigate</input> Navigate</input>

Add Pin
Remove Pin
Navigate

It is pretty self explanatory.

3. Let's add first function GetMap();

function GetMap()
{
map = new VEMap('myMap');
map.LoadMap();

var LL = new VELatLong();
LL.Longitude = '174.77620487244477';
LL.Latitude ='-41.28656222412803';

map.SetCenter(LL);
map.SetZoomLevel(16);
map.AttachEvent('onmousedown',MouseHandler);
map.AttachEvent('onmouseup',MouseHandler);
map.AttachEvent('onmousemove',MouseHandler);
map.AttachEvent('onclick', OnMapClick);


var shape = new VEShape(VEShapeType.Pushpin, map.GetCenter());
shape.SetDescription('Provoke Solutions');
shape.SetMoreInfoURL('http://www.provoke.co.nz/');
shape.SetCustomIcon('http://localhost:1221/Desktop/provoke.jpg');
shape.SetLineColor(new VEColor(0,150,100,1.0));
shape.SetFillColor(new VEColor(0,100,150,0.5));
shape.ShowIcon();
map.AddShape(shape);


}

4. Load Pins

We now need to load

function loadPins()
{
var hiddenPins = document.getElementsByTagName("input");

for( i = 0; i < hiddenPins.length; i ++)
{
if (hiddenPins[i].getAttribute('type') == 'hidden')
{
var inputID = hiddenPins[i].getAttribute('id').substr(0,5);

if (inputID == 'VEpin')
{
var oldPin = hiddenPins[i].getAttribute('id').replace('VEpin_','');
var pinDetails = hiddenPins[i].value;

var arrPinDetails = pinDetails.split(";");
var LL = new VELatLong();
LL.Longitude = arrPinDetails[2];
LL.Latitude = arrPinDetails[1];


var newPin = new VEShape(VEShapeType.Pushpin,new VELatLong(LL.Latitude, LL.Longitude));
map.AddShape(newPin);
pinId = newPin.GetID();

defaultDescription = arrPinDetails[0];
newPin.SetDescription("<div id = 'description"+pinId+"'style = 'display :block';>"+defaultDescription+"</div> <br/>"+
"<a href='#' id = 'edit"+pinId+"' onclick ='EditPinDetails(this.id)'style = 'display :block';>Edit</a>"+
"<div id = 'textChangeArea"+pinId+"' style ='display:none'> <input id='newDescription"+pinId+"' type='text' maxlength = '150' />"+
"</div><a href='#' id = 'save"+pinId+"' onclick ='SavePinDetails(this.id)'style = 'display :none';>Save</a>" );
}

}


}

}


In the next post I will take you through all the functions and what they do and how they work!!!

07 October, 2008

MSN Live Control

So at the moment I've been playing around with the new Microsoft Live controls that have been released into the developers world. The problem is that it's so new that hardly anyone has done anything with them, and if they have they haven't done anything worthwhile. I've been having a go at adding these controls as a webpart.

To get started you need to in
stall:

1. The live controls.

To download these controls, go to the Windows Live Tools Web site,
http://dev.live.com/tool

Instructions on installing the controls as well as a list of any prerequisites for the
controls are listed on this site.

2.You also require SharePoint extensions in Visual Studio.


1. Create a new webpart:


1. File > New > Project
2. Select
SharePoint > Web Part
3. Name: MSNChatWebPart

4. Location: Your development folder e.g. D:\DE
V\
5. SolutionName: MSNChatWebPart

6. Make sure your screen looks like the following :



Then hit OK.


You should now have a new Web Part project.


2. Add a Reference
  1. Find the Microsoft.Live.ServerControls.dll
  2. copy this DLL into the D:\Dev\MSNChatWebPart\ MSNChatWebPart\bin folder and also into the GAK folder of the SharePoint project.
  3. Add a reference to the above DLL in your project. Use the DLL in your bin folder.
  4. In your WebPart1.cs file add the following using statement above the namespace
using Microsoft.Live.ServerControls;


3. Adding the Control

1. You will need to programmatically add the control to the Web Part.
2. This control can be configured to your liking. For now we are going to only some basic
configuration. A full list of options is available a http:/msdn.microsoft.com/en-us/library/cc305083.aspx




I will talk more about this in a future post

3. Just note that the PrivacyStatementURL is required in order for this control to work.
For now
you can create a default page named PrivacyPolicy.aspx You n
eed to add the following code
to your project
  1. protected override void CreateChildControls()
  2. {
  3. base.CreateChildControls();
  4. //create new instance of the MSNChatControl
  5. MessengerChat myessengerChat = new MessengerChat();
  6. //add privacy statement URL path here
  7. myMessengerChat.ProvacyStatementURL = "http://~.PrivacyPolicy.aspx";
  8. //give your control an ID
  9. myMessengerChat.ID = "myMessengerChat";
  10. //add this control to the controls collention of the webpart this.Controls.Add(myessengerChat);
  11. }
This will add the MSNChat control .

4. Build your solution
5. Make sure in your Project Properties under Debug the Start browser with URL is set to your SharePoint site path
6. Deploy the solution

4. Add the web part to your site


1. Go to the design view of your page.
2. Click Add a Web Part on any zone. In this example we will add in to the middle zone
3. Expand All WebParts > and select your WebPart1 Web Part>>Add




So there we have it a nice simple MSNChat webpart for your mySite.

03 September, 2008

Introduction

So this is something new for me. I've just discovered that blogging is the new thing to do so I decided to join the fad and start my very own blog. Pretty much this blog will end up containing a lot of mush about .NET Development in C#

Yes I am aware that there are many other blogs out there that do the same thing but this one will be all mine so there. That's all the justification that I need. I think from my perspective is that this will be useful for other developers out there who are looking for solutions to issues that I may have faced and solved, something interesting I learned or just anything that I feel like ranting on about.

So far so good. I'm recently back from the Microsoft TechEd conference that was held in Auckland NZ so once my brain is back in action I will be posting some things about my learnings.