Friday, September 9, 2016

Accessing ObjectContext from DbContext in Entity Framework


There are times, we need to work with ObjectContext. To get the ObjectContext we can cast it to the IObjectContextAdapter, which resides in the System.Data.Entity.Infrastructure namespace, and call the ObjectContext as follows.
using System.Data.Entity.Infrastructure;

using (var ctx = new YourDBEntities())
{
       var objectCtx = (ctx as IObjectContextAdapter).ObjectContext;
}

The other way is to create your own partial class and expose the ObjectContext as follows:

using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;

public partial class YourDBEntities {

    public ObjectContext ObjectContext()
    {
        return (this as IObjectContextAdapter).ObjectContext;
    }
}

Then you can use with ease in all the places like:

using (var ctx = new SchoolDBEntities())
{
    var objectCtx = ctx.ObjectContext();
}

Inspired from Julie Lerman

Tuesday, October 20, 2015

The very first AngularJS application

I am very late to AngularJS development, and learning from various articles and videos. One of the Youtube video helps to start from very basics. To just check whether your page is using Angularjs  include the script path and test with an Angularjs expression.

Here is an example:

<html ng-app >
<head>
    <meta charset="utf-8" />
    <title></title>
    <script src="../js/angular.js"></script>

    <script>
        var name = "Angular";
    </script>
</head>

<body>
    <h1> Hello Angular! </h1>
    10/2 is:  {{10/2}}
</body>
</html>

If you include the correct angularjs script file, you will get the result as 5 other wise you will just see expression as it is like {{10/2}}.

Now we will move to our first Angularjs application. We have to define/use, a ng-app, angular application, a ng-controller, angular controller, and a model. First define these in the script file.

This defines the application for this page
var app = angular.module('app', []);

This creates the controller called MainController, inside the controller i am creating a model, message, and assign to the global scope.

app.controller('MainController', obj2);

function obj($scope)
{
    $scope.message = "Hello, Angular!!!";
}

Now in html page we have to tell which one is application, and which portion of the page is going to managed by the controller. I have declared my html as follows:

<html ng-app="app" >
<head>
    <meta charset="utf-8" />
    <title></title>
    <script src="../js/angular.js"></script>
    <script src="script.js"></script>
</head>
<body ng-controller="MainController">
    <h1> {{message}} </h1>
    <h3>{{message.length}} </h3>
</body>
</html>

I am setting the ng-app to the root html and whole body is managed / controlled by the controller. If you want to learn AngularJS, this article: AngularJS Tutorial: A Comprehensive 10,000 Word Guide  by Todd Motto is great one.

Sunday, February 24, 2008

log4net in sharepoint 2007

Phil Haack explains configuring log4net in asp.net 2.0 application. We can keep the configuration in the web.config, and we need to tell the log4net, that where we kept the configuration in the Application_Start() event using XmlConfiguration.Configure() menthod. In asp.net we can add a Global.asax and keep this code in Global.asax.cs.

But how can we do this in Sharepoint?

Every site collection we create in sharepoint, creates a globals.asax file and keeps in the webapp root directory. The asax files contains the following code.
<%@ Assembly Name="Microsoft.SharePoint"%>
<%@ Application Language="C#" Inherits="Microsoft.SharePoint.ApplicationRuntime.SPHttpApplication" %>
We can add a inline code in the global.asax file as follows,
<%@ Assembly Name="Microsoft.SharePoint"%>
<%@ Assembly Name="log4net, version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821" %>
<%@ Application Language="C#" Inherits="Microsoft.SharePoint.ApplicationRuntime.SPHttpApplication" %>
<%@ Import Namespace="log4net.Config" %>

<script runat="server">
void Application_Start(Object sender, EventArgs e)
{

// Configure log4Net, to take its configuration from the web.config file.
XmlConfigurator.Configure();
}
</script>
or we can derive a class from SPHttpApplication and add the Application_Start() method.

Note, as i explained here you need to keep the log4net.dll in the _app_bin directory of your sharepoint webapplication.

Cheers,
Murugan G.

Saturday, February 23, 2008

Creating a Custom Site Definition from an existing Site (template) : Part 2

Adding OTB list and our own custom list to the site.

In the first part i talked about creating a site definition from an existing site. This post talks about adding a links(MyLinks) list and a custom list (CustomListX) to the site definition.

Some background: When you want to create your own list definition, you can implement it as a sharepoint feature. When you implement as feature it is available to the whole sharepoint server, not to your specific site. It will not hurt anything, but it will mess the list of feature available to a site. For example the Posts custom list in the Blog template is available only when you create a blog site. The Posts list will not be available to any other site template, which makes more sense.

When we create our own site definition, we also want different list which should only available to our site, not for teamsite or blog site.

Now the implementation:
  • Creating the whole list and its view mostly painful job. So create the list, in our example CustomListX, in any existing site, by selecting the Custom List type, add whatever column you want.
  • Generate the list definition for the above list using Sharepoint Solution Generator app.
  • Copy the CustomListX folder, which contains a schema.xml and other .aspx files, and keep it in the List folder, under your custom site definition folder.
  • Now your folder structure looks like in the following image.

  • Now open the schema.xml in the CustomListX folder and modify the List element as follows


   1:  <List Name="CustomListX" Title="CustomListX" Description="" Url="$Resources:core,lists_Folder;/CustomListX" Direction="0" BaseType="0" xmlns="http://schemas.microsoft.com/sharepoint/" >


  • In the list element the url attribute tells, where the customlistx is located, and the basetype says it is a fresh template.
  • Open the onet.xml and look for the ListTemplates element. The generated code does not caontain any tempaltes.
  • Add the following element to ListTemplates element.

   1:  <ListTemplate Name="CustomListX" EnableModeration="False" DisplayName="CustomListX" Type="20001" BaseType="0" OnQuickLaunch="TRUE" FolderCreation="FALSE" AllowDeletion="FALSE" Unique="TRUE" DisallowContentTypes="TRUE" SecurityBits="11" Description="A sample custom List" Image="/_layouts/images/itposts.gif" />


  • The Name attribute refers to the customlistx we kept in the site definition. The Type attributes identifies it with an id. so give a valid id anything from 10000. This attribute is 103 for links, 101 for document library, and etc. For all the Type id and the list type the msdn document is here. The Unique attribute says only only list can be created based on this definition. For example in the blog site we have only one posts list, and we no need to create again and again like link or tracking list.
  • Optional. Now we will be creating the actual list to the site. Add the following List element to the Lists element in configuration element.

   1:  <List Url="$Resources:core,lists_Folder;/CustList1" QuickLaunchUrl="$Resources:core,lists_Folder;/CustList1/AllItems.aspx" Title="CustList1" Type="20001" />
  • The Url attributes says the url for the newly crated list. We are crating a list, based on CstomListX, called CustList1. The Type attribute says, the list definition (template), in our case 20001 refers the CustomListX.
  • Generate the wsp using th wspbuilder.
  • Create a site based on our customSite definition, now our new site created with a list based on the CustomListX template
  • The OTB list can be added to the site as the following List element in the Lists element.
   1:  <List FeatureId="00BFEA71-2062-426C-90BF-714C59600103" QuickLaunchUrl="$Resources:core,lists_Folder;/MyLinks/AllItems.aspx" Url="$Resources:core,lists_Folder;/MyLinks" Title="MyLinks" Type="103" />
  • The FeatureId elements says the feature of the list. In the above example we are creating list, MyLinks, based on link list. The Type element says what list type it is.
I hope we can create our won site definition for any site template, like team site, based on this example.

[update]
Download the sample code from here.

Cheers,
Murugan G.

References:
  • <12hive>\TEMPLATE\SiteTemplates\Blog

Friday, February 15, 2008

Creating a Custom Site Definition from an existing Site (template) : Part 1

The msdn here and other blogs are talks about creating a site definition from an existing site definition. Some time or most of the time we need to create a site definition from en existing (running) site, with all the modification done in the site. For example we may modified the home page, introduced new custom lists, include other asp pages. So there should be a way to do this.

In this post i will create a site definition from an existing (running) site. This example takes a Blank Site, but this can be applied to any site like Team Site.

  1. Create a blank site using “Blank Site” Template with default settings
  2. To make it simple don’t modify anything and introduce new list.
  3. Generate the site definition (source) from the newly created site, using Sharepoint Solution Generator.
  4. The solution generator creates the .csproj file Site Definition and other folder.
  5. Create a folder called CustomBlankSiteSource, this contains all the source to generate our new custom site definition
  6. We need to create a folder structure as same site template folder structure, so create a folder called 12. Inside this folder create two sub folder namely, 1033 & SiteTemplates
  7. In the 1003 folder we created above, create a folder called, xml.
  8. In the SiteTemplate folder we created above, create a folder called CustomBlankSite. This folder should be map with our new site definition name.
  9. Create a folder, xml inside the CustomBlankSite folder.
  10. Now create a xml template for the new custom site definition as follows.
   1:  <?xml version="1.0" encoding="utf-8"?>

   2:  <!-- _lcid="1033" _version="12.0.4518" _dal="1" -->

   3:  <!-- _LocalBinding -->

   4:  <Templates xmlns:ows="Microsoft SharePoint">

   5:   <Template Name="CustomBlankSite" ID="10005">

   6:      <Configuration ID="1" Title="Customized Blank Site" Hidden="FALSE" ImageUrl="/_layouts/images/blankprev.png" Description="A customized blank site to experiment site definition from Site Template (existing site)" DisplayCategory="Custom Site Definitions" AllowGlobalFeatureAssociations="False" >    </Configuration>

   7:   </Template>

   8:  </Templates>
  1. Note the template name in the above xml. This name and the folder name inside the site template should be same.
  2. The id value can be anything above 10000. Refer this msdn for further info for this id.
  3. Name this xml file as WEBTEMP_CustomBlankSite.XML and place it in CustomBlankSiteSource\12\Template\1033\XML folder.
  4. Now we have to define the whole site definition.
  5. Copy the default.aspx from the Site Definition folder, generated by the Solution Generator and place it in CustomBlankSiteSource\ 12\Template\SiteTemplates\CustomBlankSite folder.
  6. Open the onet.xml from the Site Definition folder, generated by the solution generator, and remove the AllUsersWebpart. Then copy the AllUsersWebpart from the onet.xml resides in the 12hive\TEMPLATE\SiteTemplates\sts\xml folder. There are more than one AllUsersWebpart, and you can copy from anyone. Change the image url, if you want your custom image.
  7. So now your folder and file structure looks like this.


  1. Place the wspbuilder.exe and cablib.dll inside the CustomBlankSiteSource folder.
  2. Now execute the wspbuilder from command prompt. Make sure that you are inside CustomBlankSiteSource folder in the command prompt.
  3. This creates the CustomBlankSiteSource.wsp. if you want you can use give other name as parameter to the wspbuilder.
Now you have a site definition which is created from an existing site. You can stsadm to add and deploy the solution.

The next article talks about adding default list like links, tasks, and custom list specific to our site definition.[Tips: The custom list is based on the Post list available in the blog site definition]

[update]
Download the sample code from here.

Cheers,
Murugan G.

References:

Sunday, December 9, 2007

Checkbox in ListViewWebpart

When we see the checkbox to select multiple user in People and Groups page, every (new) sharepoint developers wonders how it can be implemented to their custom list. First we will look at how it is implemented in the People and Groups (people.aspx) Page.


The people.aspx page host the UserInfo list as in the following line

<SharePoint:ListView id="UserListView" ListID="UserInfo" runat="server"/>

and the schema for the users list is defined in the schema.xml file in the <12hive>\TEMPLATE\GLOBAL\Lists\USERS folder. The checkbox is implemented as a Computed type column as follows.

<Field ID="{625e82b6-fb2b-4c37-9a45-ba7541f8d139}" Type="Computed" ReadOnly="TRUE" Name="UserSelection" DisplayName="$Resources:userinfo_schema_selectionbox;" Sortable="FALSE" Filterable="FALSE" EnableLookup="FALSE" HeaderImage="unchecka.gif" ClassInfo="Icon" AuthoringInfo="$Resources:userinfo_schema_selectionbox_editinfo;" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="UserSelection">
<FieldRefs>
<FieldRef Name="ID" />
<FieldRef Name="Name" />
<FieldRef Name="EMail" />
<FieldRef Name="SipAddress" />
<FieldRef Name="Title" />
</FieldRefs>
<DisplayPattern><HTML><![CDATA[<input type="checkbox" name="spUserSelectionCheckBox_]]></HTML>
<Counter Type="View" /><HTML><![CDATA[" id="spUserSelCb_]]></HTML>
<Counter Type="View" />
<Column Name="ID" /><HTML><![CDATA[" ]]></HTML><HTML><![CDATA[value="]]></HTML>
<Column Name="ID" HTMLEncode="TRUE" /><HTML><![CDATA[" account="]]></HTML>
<Column Name="Name" HTMLEncode="TRUE" /><HTML><![CDATA[" email="]]></HTML>
<Column Name="EMail" HTMLEncode="TRUE" /><HTML><![CDATA[" ]]></HTML><HTML><![CDATA[sip="]]></HTML>
<Column Name="SipAddress" HTMLEncode="TRUE" /><HTML><![CDATA[" ]]></HTML><HTML><![CDATA[onclick="UserSelectionOnClick(this,']]></HTML>
<Counter Type="View" /><HTML><![CDATA[');" ]]></HTML><HTML><![CDATA[title="]]></HTML>
<Column Name="Title" HTMLEncode="TRUE" /><HTML><![CDATA["/> ]]></HTML>
</DisplayPattern>
</Field>

The DisplayPattern element tells how the column should be rendered when a ListViewWebpart renders a view.

If you have list definition for your custom list you can directly go and modify the schema. When you don’t have schema but you want to achieve the checkbox in your custom list, this where comes the handy AddFieldAsXml of SpFieldCollection type.

So to add a checkbox, to select multiple listitem, in the custom list, declare a xml string as follows. (This is simplified version of DisplayPattern from the userinfo schema)
<Field Type="Computed" ReadOnly="TRUE" Name="ListItemSelection" DisplayName="Select" Sortable="FALSE" Filterable="FALSE" EnableLookup="FALSE" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="ListItemSelection">
<FieldRefs>
<FieldRef Name="ID" />
</FieldRefs>
<DisplayPattern>
<HTML><![CDATA[<input type="checkbox" ]]></HTML>
<HTML><![CDATA[LItemId="]]></HTML>
<Column Name="ID" HTMLEncode="TRUE" />
<HTML><![CDATA["/> ]]></HTML>
</DisplayPattern>
</Field>

and call the list.Fields.AddFieldAsXml(“xml string”);. Include this as a first column in your custom list’s view. You are done.



Cheers,
Murugan G.

Sunday, December 2, 2007

How do I implement client side warning/error messages in Sharepoint 2007

When you invoke Remove Users from Group menu in the Peoples and Groups (Site Actions -> Site Settings -> Peoples and Groups) without selecting any user the below warning message will be displayed.


How it is implemented. The people.aspx page in the <12hive>\ TEMPLATE\LAYOUTS, contains the following js declaration,

var noUserSelectedMsg = "<SharePoint:EncodedLiteral runat='server' text='<%$Resources:wss,people_nouserselected%>' EncodeMethod='EcmaScriptStringLiteralEncode'/>";

when we request the page the people_nouserselected string resource from wss.en-US.resx resource file is assigned to the noUserSelectedMsg. This variable later used in BtnRemoveUsersClick Js function. The Resources:wsss refers to the wss.en-US.resx file. To refer some other resource file replace the wss with your resource file.

To implement your custom resource file you can create a new assembly with you custom resource file, and keep the resx file in your C:\Inetpub\wwwroot\wss\VirtualDirectories\App_GlobalResources folder. Keep the assembly in the GAC, then declare and use as in the above example.


Cheers ,
Murugan G.