Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Tuesday, March 7, 2017

BugGuardian for ASP.NET Core

There is a new member in the BugGuardian family.

Quite a long ago, I've released BugGuardian, a library that allows you to automatically open a Bug or a Task work item on either Visual Studio Team Services or Team Foundation Server if your application experiences an unhandled exception. (Read more here)

After a while, two official extensions where released: BugGuardian.WebForms and BugGuardian.MVC. As the name states, they are targeting the ASP.NET WebForms and MVC respectively, making the adoption of BugGuardian even easier for who is using those platforms. But those 2 libraries have a limit: they only works with the traditional ASP.NET, running on the full .Net Framework.

Today, I'm very happy to announce that the BugGuardian.AspNetCore extension is finally available.

BugGuardian.AspNetCore is specifically written to support ASP.NET Core applications. It adds a Middleware to your application to let you automatically intercept all the exceptions.
And the good thing is that it supports projects with ASP.NET Core using both .Net Full Framework and Net Core.

You can find the source code (and all the information about its configuration) on GitHub here: https://github.com/n3wt0n/BugGuardian.AspNetCore

The package is also available on NuGet, here: https://www.nuget.org/packages/DBTek.BugGuardian.AspNetCore

Happy Coding :)

Tuesday, April 5, 2016

Introducing BugGuardian.MVC and BugGuardian.WebForms

Today I'm very excited to announce that I have released two additional modules for BugGuardian.

For who doesn't know it, BugGuardian is a library that allows to easily create a Bug or a Task work item on your Visual Studio Team Services account or on your on-premises Team Foundation Server 2015 in the case your application throws an Unhandled Exception.

To better support the integration of this library with web projects, today I'm announcing the availability of BugGuardian.MVC and BugGuardian.WebForms.

BugGuardian.MVC (GitHub, NuGet) is an extension for BugGuardian specifically written to support Asp.net MVC applications. 
It adds an Action Filter to your application to let you automatically intercept all the exceptions.

BugGuardian.WebForms (GitHub, NuGet), instead, is an extension for BugGuardian specifically written to support Asp.net WebForms applications.

They are based on the new BugGuardian version 1.3.0 and they support projects written with the .Net Framework v4.0 and above.

As it is for BugGuardian, these two additional libraries are OSS so feel free to see their code on GitHub.

If you encounter any issue using these libraries, please let me know through the GitHub Issues pages and I'll fix the problem as soon as possible!

Again, I want to thanks my friend and fellow MVP Marco Minerva (@marcominerva, GitHub) for the support and the suggestions.

Thursday, August 20, 2015

Welcome BugGuardian

Someone of you has maybe noticed the I did only few post in the last months. This happened because of two main reasons.

The first one is, as some of you already know, I moved in another country far away from home, with a completely different culture and language, to start a new adventure. This inevitably took a lot of time from the already small amount of spare time I have.

The second reason I wasn't so active here, that is also the reason of this post, is that I worked on a new project that I have released today: BugGuardian.

What is BugGuardian
BugGuardian is an Open Source library, written in C# like Shared Project, that allows to easily create a Bug work item on your Visual Studio Online account or on your on-premises Team Foundation Server 2015 in the case your application throws an Unhandled Exception.
It can also be invoked manually in try/catch blocks to keep track of handled exceptions.

It supports applications written with the .Net Framework v4.0 and above, and it can be used on every kind of project, including:
  • Asp.net
  • Asp.net MVC
  • WPF
  • Windows 8 / 8.1 Apps
  • Windows Phone 8 / 8.1 Apps
  • Universal App
  • Universal Windows Platform Apps (Windows 10)
  • and so on...

As I mentioned, it is OSS so you can find the sources on GitHub.

To let you install and use it without having to build the sources by your own, I have published it on NuGet. Just search for BugGuardian in the Package Manager GUI or run the following command in the Package Manager Console:
Install-Package DBTek.BugGuardian

Usage, support and Feedback
Refer to the project documentation to find examples about how to use this library. You can also find some code samples in the TestApps folder.

Anyway, just to make an example and to show it's really simple to use, this is the code you need to manage an exception and to open a Bug on your VSO / TFS:

using (var creator = new DBTek.BugGuardian.Creator())
{
    creator.AddBug(myException);
}

If you encounter any issue using this library, please let me know through the Issues page and I'll fix the problem as soon as possible!

I'm waiting for your feedback :)


I want to thank you my friend and fellow MVP Marco Minerva (@marcominerva) for the support, the patience and the Code Review.

Tuesday, June 16, 2015

Create a RSS reader in an Umbaco 7 MVC Partial View

There are several way to create and embed a RSS reader in an Umbraco page: using custom controllers, using XSL macros, etc...

But wath if we want to use a normal MVC Partial View without to develop a custom controller?

Well, it is really simple to achieve this goal with just a few C# lines.

@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@using System.ServiceModel
@using System.ServiceModel.Syndication
@using System.Xml
@{
 string url = "http://your_blog_rss_url";
 XmlReader reader = XmlReader.Create(url);
 SyndicationFeed feed = SyndicationFeed.Load(reader); 
 reader.Close(); 
}

@foreach(var feedItem in feed.Items)
{ 
 <div class="col-md-6">
  <article>
   <div class="date">
    <span class="day">@feedItem.PublishDate.Day</span>
    <span class="month">@GetMonthName(feedItems[i].PublishDate.Month)</span>
   </div>
   <h4 class="heading-primary"><a href="@feedItem.Links[4].Uri">@feedItems[i].Title.Text</a></h4>
   <p>@(feedItem.Summary.Text + "... ") <a href="@feedItem.Links[4].Uri" class="read-more">read more <i class="fa fa-angle-right"></i></a></p>
  </article>
 </div>
}

As you can see, only a couple odlines are required. At this point we just have to include this partial view in the page where we want to see our RSS feed.
Obviously, you can change the layout (the one here is what I used in my project).

Only 2 notes:
  1. I used "feedItem.Links[4].Uri" to retrieve the blog post url, this works if you use blogger. If you use other blogging platforms as sources, you'll have to check the Links collection to know "where" is the url you want.
  2. The "@GetMonthName" is just an Helper to convert the "number" of the month into its name.

Monday, July 14, 2014

ASP.net MVC ActionLink with Image: Part 3 (Ajax)

In my previous posts we've seen how to implement some custom helpers to add  Bootstap Glyphs or Images to ActionLinks.

Now we're going to see how to do the same thing but with Ajax support too.

The basic things to do is to build the html code taking care of all the "ajax-related stuff" that the normal Ajax.ActionLink helper adds.

In this example I used the glyph as image, but you can use the same approach also with the normal images.

/// <summary>
/// Create an Ajax.ActionLink with an associated glyphicon
/// </summary>
/// <param name="htmlHelper"></param>
/// <param name="linkText"></param>
/// <param name="actionName"></param>
/// <param name="controllerName"></param>
/// <param name="glyphicon"></param>
/// <param name="routeValues"></param>
/// <param name="htmlAttributes"></param>
/// <returns></returns>
public static MvcHtmlString ImageActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, string glyphicon, AjaxOptions ajaxOptions, RouteValueDictionary routeValues = null, object htmlAttributes = null)
{
 //Example of result:           
 //<a id="btnShow" href="/Customers/ShowArtworks?customerId=1" data-ajax-update="#pnlArtworks" data-ajax-success="jsSuccess" 
 //data-ajax-mode="replace" data-ajax-method="POST" data-ajax-failure="jsFailure" data-ajax-confirm="confirm" data-ajax-complete="jsComplete" 
 //data-ajax-begin="jsBegin" data-ajax="true">
 //  <i class="glyphicon glyphicon-pencil"></i>
 //  <span>Edit</span>
 //</a>

 var builderI = new TagBuilder("i");
 builderI.MergeAttribute("class", "glyphicon " + glyphicon);
 string iTag = builderI.ToString(TagRenderMode.Normal);

 string spanTag = "";
 if (!string.IsNullOrEmpty(linkText))
 {
  var builderSPAN = new TagBuilder("span");
  builderSPAN.InnerHtml = " " + linkText;
  spanTag = builderSPAN.ToString(TagRenderMode.Normal);
 }

 //Create the "a" tag that wraps
 var builderA = new TagBuilder("a");

 var requestContext = HttpContext.Current.Request.RequestContext;
 var uh = new UrlHelper(requestContext);

 builderA.MergeAttribute("href", uh.Action(actionName, controllerName, routeValues));

 //Ajax section
 builderA.MergeAttribute("data-ajax", "true");
 builderA.MergeAttribute("data-ajax-update", ajaxOptions.UpdateTargetId.StartsWith("#") ? ajaxOptions.UpdateTargetId : "#" + ajaxOptions.UpdateTargetId);
   
 if (!string.IsNullOrEmpty(ajaxOptions.InsertionMode.ToString()))
  builderA.MergeAttribute("data-ajax-mode", ajaxOptions.InsertionMode.ToString());            
 
 if (!string.IsNullOrEmpty(ajaxOptions.OnBegin))
  builderA.MergeAttribute("data-ajax-begin", ajaxOptions.OnBegin);
 
 if (!string.IsNullOrEmpty(ajaxOptions.OnComplete))
  builderA.MergeAttribute("data-ajax-complete", ajaxOptions.OnComplete);
   
 if (!string.IsNullOrEmpty(ajaxOptions.OnFailure))
  builderA.MergeAttribute("data-ajax-failure", ajaxOptions.OnFailure);
   
 if (!string.IsNullOrEmpty(ajaxOptions.OnSuccess))
  builderA.MergeAttribute("data-ajax-success", ajaxOptions.OnSuccess);
   
 if (!string.IsNullOrEmpty(ajaxOptions.Confirm))
  builderA.MergeAttribute("data-ajax-confirm", ajaxOptions.Confirm);
  
 if (!string.IsNullOrEmpty(ajaxOptions.HttpMethod))
  builderA.MergeAttribute("data-ajax-method", ajaxOptions.HttpMethod);

 if (htmlAttributes != null)
 {
  IDictionary<string, object> attributes = new RouteValueDictionary(htmlAttributes);
  builderA.MergeAttributes(attributes);
 }

 builderA.InnerHtml = iTag + spanTag;

 return new MvcHtmlString(builderA.ToString(TagRenderMode.Normal));
}


As you can see, the code is similar to the one we've seen in the other posts but with the exception of the fact we are extending an "AjaxHelper" insetead of  an "HtmlHelper" and the add of the "ajax section"

Wednesday, July 9, 2014

ASP.net MVC ActionLink with Image: Part 2 (using Images)

In my previous post I talked about creating a custom helper to render an ActionLink with a Glyph image.

In this post I will show how to create a similar helper but using "normal" images instead of bootstrap glyphs.

/// <summary>
/// Create an ActionLink with an associated image
/// </summary>
/// <param name="htmlHelper"></param>
/// <param name="linkText"></param>
/// <param name="actionName"></param>
/// <param name="controllerName"></param>
/// <param name="imagePath"></param>
/// <param name="routeValues"></param>
/// <param name="htmlAttributes"></param>
/// <returns></returns>
public static MvcHtmlString ImageImgActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, string imagePath, object routeValues = null, object htmlAttributes = null)
{
 //Exemple of result:
 //<a href="@Url.Action("Edit", new { id = Model.id_rod })">
 //  <i class="glyphicon glyphicon-pencil"></i>
 //  <span>Edit</span>
 //</a>

 if (imagePath.StartsWith("~/"))
 {
  imagePath = VirtualPathUtility.ToAbsolute(imagePath);
 }

 var builderImage = new TagBuilder("image");
 builderImage.MergeAttribute("src", imagePath);
 builderImage.MergeAttribute("alt", linkText);
 builderImage.MergeAttribute("style", "border=0");
 string imageTag = builderImage.ToString(TagRenderMode.SelfClosing);

 string spanTag = "";
 if (!string.IsNullOrEmpty(linkText))
 {
  var builderSPAN = new TagBuilder("span");
  builderSPAN.InnerHtml = " " + linkText;
  spanTag = builderSPAN.ToString(TagRenderMode.Normal);
 }

 //Create the "a" tag that wraps
 var builderA = new TagBuilder("a");

 var requestContext = HttpContext.Current.Request.RequestContext;
 var uh = new UrlHelper(requestContext);

 builderA.MergeAttribute("href", uh.Action(actionName, controllerName, routeValues));

 if (htmlAttributes != null)
 {
  IDictionary<string, object> attributes = new RouteValueDictionary(htmlAttributes);
  builderA.MergeAttributes(attributes);
 }

 builderA.InnerHtml = imageTag + spanTag;

 return new MvcHtmlString(builderA.ToString(TagRenderMode.Normal));
}


You can pass to the helper both absolute urls or relative urls (as imagePath) so it gives you total flexibility.

Monday, July 7, 2014

ASP.net MVC ActionLink with Image: Part 1 (using Glyph)

If you are using ASP.net MVC you surely know that there is an helpful helper to create a link that points to an Action of a controller: it's the Html.ActionLink.

You can use this helper only with text, but what about if you want to add to the link a glyph image, like in this example?



Well, the "fast&dirty" answer is to write some html directly in the cshtml page. Something like:

<a href="@Url.Action("Edit", new { id = Model.id })">
  <i class="glyphicon glyphicon-pencil"></i>
  <span>Edit</span>
</a>


This approach is faster that any other, if you need to have it only in few places. But what about if you have to use it spread all around you application (as in my case?). You will have to copy&paste the code all around and then change it. Not so good...

The better way to do it, in this case, is to write a custom helper that will do it for you.

/// <summary>
/// Create an ActionLink with an associated glyphicon
/// </summary>
/// <param name="htmlHelper"></param>
/// <param name="linkText"></param>
/// <param name="actionName"></param>
/// <param name="controllerName"></param>
/// <param name="glyphicon"></param>
/// <param name="routeValues"></param>
/// <param name="htmlAttributes"></param>
/// <returns></returns>
public static MvcHtmlString ImageActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, string glyphicon, object routeValues = null, object htmlAttributes = null)
{
 //Exemple of result:
 //<a href="@Url.Action("Edit", new { id = Model.id_rod })">
 //  <i class="glyphicon glyphicon-pencil"></i>
 //  <span>Edit</span>
 //</a>

 var builderI = new TagBuilder("i");
 builderI.MergeAttribute("class", "glyphicon " + glyphicon);
 string iTag = builderI.ToString(TagRenderMode.Normal);

 string spanTag = "";
 if (!string.IsNullOrEmpty(linkText))
 {
  var builderSPAN = new TagBuilder("span");
  builderSPAN.InnerHtml = " " + linkText;
  spanTag = builderSPAN.ToString(TagRenderMode.Normal);
 }            

 //Create the "a" tag that wraps
 var builderA = new TagBuilder("a");

 var requestContext = HttpContext.Current.Request.RequestContext;
 var uh = new UrlHelper(requestContext);
 
 builderA.MergeAttribute("href", uh.Action(actionName, controllerName, routeValues));

 if (htmlAttributes != null)
 {
  IDictionary<string, object> attributes = new RouteValueDictionary(htmlAttributes);
  builderA.MergeAttributes(attributes);
 }
  
 builderA.InnerHtml = iTag + spanTag;
 
 return new MvcHtmlString(builderA.ToString(TagRenderMode.Normal));
}

At this point it will be possible to invoke the Html.ImageActionLink helper in the same way and with the same parameters that we will use with the "normal" Html.ActionLink plus the glyphicon class of the glyph image we wanna add to the link.

Wednesday, June 5, 2013

GridView Scroll to a desired group in a Windows Store App

By default, in a Windows Store App, the focus in a GridView is given to the element "0" of the group "0". But what if you wanto to change this behaviour and make it "open" to another element?

To do it, you have to manage the  itemGridView_Loaded event and use the CollectionView:

In XAML:
<GridView
    x:Name="itemGridView"
    AutomationProperties.AutomationId="ItemGridView"
    AutomationProperties.Name="Grouped Items"
    Grid.RowSpan="2"
    Padding="116,137,40,46"
    ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
    ItemTemplate="{StaticResource Standard250x250ItemTemplate}"
    SelectionMode="None"
    IsSwipeEnabled="false"
    IsItemClickEnabled="True"
    ItemClick="ItemView_ItemClick"
    Loaded="itemGridView_Loaded">

Incode-behind:
private bool firstTime = true;
        
   private void itemGridView_Loaded(object sender, RoutedEventArgs e)
   {
        ICollectionView view;
        ICollectionViewGroup myGroup;
        Data.MyDataType myItem;
 
        if (!this.firstTime) return; else firstTime = false;
        view = itemGridView.ItemsSource as ICollectionView;
        view.CurrentChanged += view_CurrentChanged;
        int groupIndex = 2; // an integer value between 0 and # of items in the groups collection
        myGroup = view.CollectionGroups[groupIndex] as ICollectionViewGroup;
        myItem = recipeGroup.GroupItems[0] as Data.MyDataType;
        view.MoveCurrentTo(myItem);
    }
     
    private void view_CurrentChanged(object sender, object e)
    {
        ICollectionView view;
        Data.MyDataType  myItem;
         
        view = itemGridView.ItemsSource as ICollectionView;
        view.CurrentChanged -= view_CurrentChanged;
        myItem = view.CurrentItem as Data.MyDataType;
        itemGridView.ScrollIntoView(view.CurrentItem, ScrollIntoViewAlignment.Leading);
    }

Wednesday, May 29, 2013

Privacy Policy in Charm Bar: the easiest way

When you make a Windows Store App, if it uses any Network connection, you have to specify your Privacy Settings in both Store page and Charm Bar.

But how to do it? What's the simplest way?

So, here's the answers.

Do the following in your App.xaml.cs:

1) Add the namespaces
using Windows.UI.ApplicationSettings;
using Windows.UI.Popups;


2) Add the handler during app initialization (into OnLaunched())
SettingsPane.GetForCurrentView().CommandsRequested += SettingCharmManager_CommandsRequested;


3) Add my handler that shows the privacy text
private void SettingCharmManager_CommandsRequested(SettingsPane sender, SettingsPaneCommandsRequestedEventArgs args)
{

    args.Request.ApplicationCommands.Add(new SettingsCommand("privacypolicy", "Privacy policy", OpenPrivacyPolicy));

}

4) Add OpenPrivacyPolicy method
private async void OpenPrivacyPolicy(IUICommand command)

{

    Uri uri = new Uri("http://my_website/my_privacy.html");
    await Windows.System.Launcher.LaunchUriAsync(uri);

}


Tuesday, May 14, 2013

Free technical e-book on the Microsoft platform


While a lot of information on application development is available on the internet and in books, that information is becoming harder to digest. If you do not enjoy reading several 500+ page books, or scouring the web for relevant blog posts and articles, you have come to the right place.
Syncfusion publishes the Succinctly series concise technical books that target developers working on the Microsoft platform. Each book is around 100 pages and is guaranteed to enlighten you on the topic of interest. Download a copy, get a cup of your favorite beverage, and enjoy!

Tuesday, March 12, 2013

LINQ Optimization tips

1. Any or Count?
When you have to test for the presence of at least one element into a list, use
        if (query.Any())
Instead of
        if (query.Count() > 0)
That way it only needs to find the first match.

2. Conditions
Use
        query.FirstOrDefault(x => x.value > 1);
        query.SingleOrDefault(x => x.value > 1);
Instead of
        query.Where(x => x.value > 1).FirstOrDefault();
        query.Where(x => x.value > 1).SingleOrDefault();
That way it only does one operation instead of two concatenated operations

3. Understand how it works
You always need to struggle for performance as a LINQ Developer; perhaps because to understand better how internal mechanism works.
        using (MYDataContext context = new MYDataContext())
        {
            var customers = from cust in context.Customers
                            select cust;
            foreach (var customer in customer)
                Response.Write(customer.CustomerAddresses.Count().ToString());
        }
In above example, you will see in Sql Server Profiler that for each customer one query will be executed additional each times to get the total addresses count for that customer when you enumerates in foreach loop. Now, consider below re-written snippet:
        using (MYDataContext context = new MYDataContext())
        {
            var customers = from cust in context.Customers
                            select cust;
            DataLoadOptions dataLoadOptions = new DataLoadOptions();
            dataLoadOptions.LoadWith(A => A.CustomerAddresses);
            context.LoadOptions = dataLoadOptions;
            foreach (var customer in customer)
                Response.Write(customer.CustomerAddresses.Count().ToString());
        }
Simply in above example, with DataLoadingOptions we are infect just telling LINQ Query engine that while it fetches the Customer data; also fetch associated CustomerAddresses table record count for that particular Customer. The benefit is; only ONE query will be executed to get the final result.

4. Finally
The success behind a LINQ application that you develop lies behind the performance of the query that you formulate. You can use any third party tool like I prefer to use LINQPad (by Joseph Albahari) while my development with LINQ. Actually, quick since a long time after I got to know about this tool and I was impressed so much that I thought to why not I get aware something about such nice and intelligent tool before. Life would have become easier!

Thursday, December 20, 2012

Monitor a Task time out

There are some ways to wait for a task timeout. This is the simplest:
using System.Threading.Tasks;

[...]

try
{
    Task executeTask = STask.Factory.StartNew(() => DoSomething());

    //Wait for 5 minutes
    int index = System.Threading.Tasks.Task.WaitAny(new[] { executeTask },
     TimeSpan.FromSeconds(300));

    if (index == -1)
    {
        //Task execution Time Out
    }
    else
    {
        //Task executed in-time
    }
}
catch (AggregateException aex)
{
    foreach (Exception ex in aex.InnerExceptions)
        LogError(ex, ex.Message);
}
catch (Exception ex)
{
    LogError(ex, "Error");
}

Tuesday, September 20, 2011

DataTable sorting

Sort a DataTable is a very simple activity:


[VB.Net]
dt.DefaultView.Sort = "ColumnName"  'normal DataTable 

ds.Tables("TableName").DefaultView.Sort = "ColumnName"  'DataTable in DataSet


[C#]
dt.DefaultView.Sort = "ColumnName"  'normal DataTable

ds.Tables["TableName"].DefaultView.Sort = "ColumnName"  'DataTable in DataSet


With this snippet you don't "physically" order the content of the DataTable but it's default view. But for data visualization purpose and other the result is the same.
Using this DataTable, for example, as datasource for a GridView the list will be sorted based of the used criteria (ColumName).

Wednesday, May 4, 2011

Using C# and VB.net togheter in Asp.net

To use in the same Asp.net Web Application classes written in different languages, such C# and VB.net, you have to do this steps:

Create in the App_Code folder two subfolder, called for example VB and CS:

App_Code
->VB
->CS

Next, add in the web.config this lines:
<system.web>
[...]
<compilation>
<codeSubDirectories>
<
add directoryName="CS"/>
<add directoryName="VB"/>
codeSubDirectories>
[...]
compilation>
system.web>

And voila, its done!

PS: obviously, you have to put all vb.net classes in a folder and all the c# classes in the other folder...

Saturday, July 12, 2008

Error management on ASP.Net pages

How are managed errors ASP.Net pages?

A way is to modify the event "onError", in Global.asax, and make a server transfer to errors-management pages, tipically for error 500 and error 404.
We can also insert here the code to send a mail in case of error.

But the best thing is to create an HttpModule to intercept error events:

C#
public class ErrorModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.Error += new System.EventHandler(context_Error);
    }

    private void context_Error(object sender, System.EventArgs e)
    {
        Exception exception = HttpContext.Current.Server.GetLastError();
    }

    public void Dispose()
    {
    ...
    }
}

VB.Net
Public Class ErrorModule
    Inherits IHttpModule

    Public Sub Init(ByVal context As HttpApplication)
        AddHandler context.Error, AddressOf Me.context_Error
    End Sub

    Private Sub context_Error(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim exception As Exception = HttpContext.Current.Server.GetLastError
    End Sub

    Public Sub Dispose()
        ...
    End Sub
End Class

and then register it in the Web.config:

<system.web>
    <httpModules>
        <add name="ErrorModule" type="ErrorModule" />
    </httpModules>
</system.web>



HttpModules are "the better ways", 'cause permit reusability and its possible to enable or disable them from Web.config without recompile.