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

Thursday, 27 November 2014

C# code to download a file from a website URL

Hi All,
Yesterday one of my colleagues was having issue with downloading a file from URL using c# for one of the projects. This is a general requirement for many projects and thought it would be helpful if I post here.

using System;
using System.IO;
using System.Net;
using System.Text;

namespace FileDownloadSample
{
    class Program
    {
        static void Main(string[] args)
        {

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.yoursite.com/yourfile.pdf");

            request.Method = "GET";

            var encoding = new UTF8Encoding();

            request.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-gb,en;q=0.5");
            request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate");

            request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
            request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0";

            var resp = (HttpWebResponse)request.GetResponse();

           

            using (var stream = File.Create("TargetFileName.pdf"))
                resp.GetResponseStream().CopyTo(stream);


        }
    }
}

Tuesday, 1 July 2014

C#.Net - Handling special characters in XML strings

Because XML syntax uses some characters for tags and attributes it is not possible to directly use those characters inside XML tags or attribute values.
To include special characters inside XML files you must use the numeric character reference instead of that character. The numeric character reference must be UTF-8 because the supported encoding for XML files is defined in the prolog as encoding="UTF-8" and should not be changed.
The numeric character reference uses the format:

&#nn;  decimal form
&#xhh; hexadecimal form
We can use the SecurityElement.Escape method to replace the invalid XML characters in a string with their valid XML equivalent [1]. 
1
2
//Usage
srtXML = SecurityElement.Escape(strXML);
Namespace: System.Security
Assembly: mscorlib (in mscorlib.dll)
I have used the HttpUtility classes UrlEncode and UrlDecode methods to handle cross-site scripting attacks and this also helped me to get rid of the XmlException – “Data at the root level is invalid”.
The following table shows the invalid XML characters and their respective replacements.

CodeNameDisplayed as
	Horizontal tabnon-printing

Line feednon-printing

Carriage Returnnon-printing
 Spacenon-printing
!Exclamation mark!
"Quotation mark"
#Number sign#
$Dollar sign$
%Percent sign%
&Ampersand&
'Apostrophe'
(Left parenthesis(
)Right parenthesis)
*Asterisk*
+Plus sign+
,Comma,
-Hyphen-
.Period.
/Slash/
:Colon:
&#59;Semi-colon;
&#60;Less than<
&#61;Equals sign=
&#62;Greater than>
&#63;Question mark?
&#64;At@
&#91;Left square bracket[
&#92;Bbackslash\
&#93;Right square bracket]
&#94;Caret^
&#95;Underscore_
&#96;Acute accent`
&#123;Left curly brace{
&#124;Vertical bar|
&#125;Right curly brace}
&#126;Tilde~

Reference:
1. MSDN


Thursday, 13 February 2014

New Features in C#.Net 5.0

Here are some of the C#.NET 5.0 New Features -

1. Key Features Matrix: Microsoft has published a new version of C# 5.0 beta with CLR version 4.5.

Key Features introduced in C# .Net 5.0

C# 5.0 introduces mainly two key features: Async Programming and Caller Information.

2. Asynchronous functions (Async and Await): Using Async and Await, you can use resources in the .NET Framework, to create an asynchronous method as easily as you create a synchronous method.

Asynchronous methods are the methods that you define using async and await.

Click on this http://codejunction.blogspot.in/2014/02/new-features-added-in-c-50.html to know more about async and await.

3. Caller Information: Caller Information attributes provide the information about the caller to a method. You can obtain the file path of the source code, the line number in the source code, and the member name of the caller. Caller Information helps us in tracing, debugging, and creating diagnostic tools.

CallerFilePathAttribute - Full path of the source file that contains the caller. This is the file path used at compile time.

CallerLineNumberAttribute - Line number in the source file on which the method is called.

CallerMemberNameAttribute - Method or property name of the caller.

4. Windows Runtime Support: C# and .NET now have deep integration with the Windows Runtime. C# project can compiled into a WinMD file and then referenced from a HTML/JavaScript project. WinRT’s flavor of COM uses the same metadata format used by the Common Language Runtime. This information is stored in WINMD files that show the structure, though not the implementation, of all the public classes. Windows Runtime returns an HRESULT instead of throwing an exception. For well-known HRESULT values, the corresponding exception is thrown, otherwise a COMException is used.

Read this article for more information on C# and Visual Basic on the WinRT API.

5. Compiler APIs: This feature is supposed to come after C# 5.0 – the APIs will expose whatever knowledge the compiler has about the code to the IDE and the developers, through Syntax Tree APIs, Symbol APIs, Binding and Flow analysis APIs and Emit APIs.

References:

http://msdn.microsoft.com/en-us/library/hh156499.aspx

http://www.infoq.com/news/2011/09/net-v5.0

Thursday, 31 October 2013

New features added in C# 5.0

C# most recent version 5.0 was released on August 15, 2012 with .NET Framework 4.5 and Visual Studio 2012.

There are two main features in C# 5.0 - Async Programming and Caller Information. Let's understand both these features in details as given below.

Async Feature (Asynchronous Methods)

C# 5.0 Async feature introduces two keywords async and await which allows you to write asynchronous code more easily and intuitively like as synchronous code. Before C# 5.0, for writing an asynchronous code, you need to define callbacks (also known as continuations) to capture what happens after an asynchronous process finishes. This makes your code and other routine task such exception handling complicated.

Both the keywords are used in a combination of each other. Hence, an await operator is applied to a one or more than one expressions of an async method. An async method returns a Task or Task<TResult> that represents the ongoing work of the method. The task contains information that the caller of the asynchronous method can use, such as the status of the task, its unique ID, and the method's result.

  1. public async Task<IEnumerable<Product>> GetProductList()

  2. {

  3. HttpClient client = new HttpClient();

  4. Uri address = new Uri("http://dotnet-tricks.com/");

  5. client.BaseAddress = address;

  6.  
  7. HttpResponseMessage response = await client.GetAsync("myservice/product/ProductList");

  8.  
  9. if (response.IsSuccessStatusCode)

  10. {

  11. var list = await response.Content.ReadAsAsync<IEnumerable<Product>>();

  12. return list;

  13. }

  14. else

  15. {

  16. return null;

  17. }

  18. }


Caller Information (Caller info attributes)


Caller Information can help you in tracing, debugging and creating diagnose tools. It will help you to avoid duplicate codes which are generally invoked in many methods for same purpose, such as logging and tracing.

You could get the following information of caller method:



  1. CallerFilePathAttribute


    Full path of the source file that contains the caller. This is the file path at compile time.



  2. CallerLineNumberAttribute


    Line number in the source file at which the method is called.



  3. CallerMemberNameAttribute


    Method or property name of the caller.

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. class Example
  8. {
  9. static void Main(string[] args)
  10. {
  11. Console.WriteLine("Main method Start");
  12. InsertLog("Main");
  13. MyMethodB();
  14. MyMethodA();
  15. Console.WriteLine("Main method End!");
  16. Console.ReadLine(); // hold on result
  17. }
  18.  
  19. static void MyMethodA()
  20. {
  21. InsertLog("MyMethodA");
  22. MyMethodB();
  23. }
  24.  
  25. static void MyMethodB()
  26. {
  27. // some code here.
  28. }
  29.  
  30. static void InsertLog(string method)
  31. {
  32. Console.WriteLine("{0} called MyMethodB at {1}", method,
  33. DateTime.Now);
  34. }
  35. }
  36. /* Output:
  37. Main method Start
  38. Main called MyMethodB at 11/17/2013 11:12:24 PM
  39. MyMethodA called MyMethodB at 11/17/2013 11:12:24 PM
  40. Main method End!
  41. */

In both Main and MyMethodA, method InsertLog is invoked for logging. Now we can change the above code as follows.

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.CompilerServices;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. class Example
  8. {
  9. static void Main(string[] args)
  10. {
  11. Console.WriteLine("Main method Start");
  12. MyMethodB();
  13. MyMethodA();
  14. Console.WriteLine("Main method End!");
  15. Console.ReadLine();
  16. }
  17.  
  18. static void MyMethodA()
  19. {
  20. MyMethodB();
  21. }
  22.  
  23. static void MyMethodB([CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
  24. {
  25. InsertLog(memberName);
  26. }
  27.  
  28. static void InsertLog(string method)
  29. {
  30. Console.WriteLine("{0} called MyMethodB at {1}", method, DateTime.Now);
  31. }
  32. }
  33.  
  34. /*Output:
  35. Main method Start
  36. Main called MyMethodB at 11/17/2013 10:30:11 PM
  37. MyMethodA called MyMethodB at 11/17/2013 10:30:11 PM
  38. Main method End!
  39. */


Hope you like these new features of C# 5.0.

Thursday, 18 July 2013

.Net c# parallel yield

yield is a very useful keyword in C# that allows you to create dynamic enumerators of stuffs without having to fill in a List<T> of things you want to return first. The generated code builds a state machine that will go forward, step by step, whenever the caller calls MoveNext on the IEnumerable it gets back (usually using foreach).


static void Main(string[] args)
{
    var input = new[] { "A", "B", "C" };
 
    Console.WriteLine(String.Join("\n", Process(input)));
}
 
static IEnumerable<string> Process(IEnumerable<string> input)
{
    if (input == null)
        throw new ArgumentNullException("input");
 
    foreach (var item in input)
    {
        yield return "Process " + item;
    }
}
 
// Output :
// Process A
// Process B
// Process C
 
The second really useful thing is Parallel.ForEach. Whenever you have to process loads of independent data that are CPU hungry you can launch the process in parallel and have it scheduled for you by the .NET runtime.

static void Main(string[] args)
{
    var input = new[] { "A", "B", "C" };
 
    Stopwatch w = new Stopwatch();
    w.Start();
    Process(input);
    w.Stop();
 
    Console.WriteLine("{0}s ", w.Elapsed.TotalSeconds);
}
 
static void Process(IEnumerable<string> input)
{
    if (input == null)
        throw new ArgumentNullException("input");
 
    Parallel.ForEach(input, item =>
        {
            // Something long
            Thread.Sleep(1000);
        });
}
 
// Output :
// ~ 1s although we had 3 stuffs that each took 1s
 
What if we could write that?

 
static void Main(string[] args)
{
    var input = new[] { "A", "B", "C" };
 
    Stopwatch w = new Stopwatch();
    w.Start();
    var result = Process(input);
    w.Stop();
 
    Console.WriteLine("{0}s ", w.Elapsed.TotalSeconds);
    Console.WriteLine(String.Join("\n", result));
}
 
static IEnumerable<string> Process(IEnumerable<string> input)
{
    if (input == null)
        throw new ArgumentNullException("input");
 
    Parallel.ForEach(input, item =>
        {
            // Something long
            Thread.Sleep(1000);
             
            // >>>> THE POWER !!
            yield return "Process " + item;
        });
}
 
But no we can’t because “The yield statement cannot be used inside an anonymous method or lambda expression“.
You obviously can’t mix those two pieces of magic together. In fact, if we could this would produce some of the weirdest bugs ever if something went wrong. But maybe we can’t build something that looks like it, for the sake of doing it?

static void Main(string[] args)
{
    var input = new[] { "A", "B", "C" };
 
    Stopwatch w = new Stopwatch();
    w.Start();
    var result = Process(input);
 
    Trace.WriteLine(String.Format("{0}s before enumerating", w.Elapsed.TotalSeconds));
    Trace.WriteLine(String.Format(String.Join("\n", result)));
    Trace.WriteLine(String.Format("{0}s after enumerating", w.Elapsed.TotalSeconds));
}
 
static IEnumerable<string> Process(IEnumerable<string> input)
{
    if (input == null)
        throw new ArgumentNullException("input");
 
    var workQueue = new ConcurrentQueue<string>();
    Exception workException = null;
    var completed = false;
 
    // This task will run on its side in another thread
    Task.Run(() =>
    {
        try
        {
            Parallel.ForEach(input, item =>
                {
                    // Something long
                    Thread.Sleep(1000);
 
                    // Push our results here
                    workQueue.Enqueue("Process " + item);
                });
        }
        catch (Exception ex)
        {
            // We don't want a crash to be lost in another thread
            // so we have to bring it back somehow on the main thread
            workException = ex;
        }
 
        completed = true;
    });
 
    // Not the most elegant, but it's just for fun so ...
    while (!completed)
    {
        string item;
        if (workQueue.TryDequeue(out item))
            yield return item;
        else
            Thread.Sleep(1); // remember, just for fun
    }
 
    // We don't want to lose the last items
    string finalItem;
    while (workQueue.TryDequeue(out finalItem))
        yield return finalItem;
 
    // Buble the exception if there's one
    if (workException != null)
    {
        throw new Exception("Error while doing stuffs", workException);
    }
}
Output:
0.00039s before enumerating
Process B
Process A
Process C
1.0398348s after enumerating
Notice than we did have an “yield behavior” as the processing was not executed on the call to Process, and how the whole process took 1s where it has 3 items that each took 1s. We also don’t have a reliable order anymore, it could have been any combination of B, A and C.

Friday, 22 July 2011

SplineSeries for the Silverlight Toolkit - C# Code

While the Silverlight Toolkit has made some amazing strides in improving, it still lacks some functionality compared to other toolkit offerings. In particular, Silverlight Toolkit's charts lack splines, or smoothed lines. The idea here is that we don't want the graph to appears as though a line is moving from point to point directly -- that it moves parabolically, or softer.




A typical line series.



Now, this is all fun and games, but can we get something where transitions are more smooth? Yes, we can.




A spline series.



Notice, the spline series changes are more gradual and curved. Are they an entirely accurate representation of the in-between? No, not always -- but they're not meant to be (necessarily).



The Spline Series is literally a copy/paste of the LineSeries, with a few changes. Note that this is located under the Charting/Series folder of the DataVisualization.Toolkit project. Essentially, what we want to do is change the Polyline to a Path. The idea here is that a Polyline doesn't draw Beziers. Below is my (large) code,



SplineSeries.cs:



// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
 
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Windows.Media;
using System.Windows.Shapes;
 
#if !DEFINITION_SERIES_COMPATIBILITY_MODE
 
namespace System.Windows.Controls.DataVisualization.Charting
{
    /// <summary>
    /// Represents a control that contains a data series to be rendered in X/Y 
    /// line format.
    /// </summary>
    /// <QualityBand>Preview</QualityBand>
    [StyleTypedProperty(Property = DataPointStyleName, StyleTargetType = typeof(LineDataPoint))]
    [StyleTypedProperty(Property = "LegendItemStyle", StyleTargetType = typeof(LegendItem))]
    [StyleTypedProperty(Property = "PathStyle", StyleTargetType = typeof(Path))]
    [TemplatePart(Name = DataPointSeries.PlotAreaName, Type = typeof(Canvas))]
    [SuppressMessage("Microsoft.Maintainability", "CA1501:AvoidExcessiveInheritance", Justification = "Depth of hierarchy is necessary to avoid code duplication.")]
    public partial class SplineSeries : LineAreaBaseSeries<LineDataPoint>
    {
        #region public PointCollection Points
        /// <summary>
        /// Gets the collection of points that make up the spline.
        /// </summary>
        public PointCollection Points
        {
            get { return GetValue(PointsProperty) as PointCollection; }
            private set { SetValue(PointsProperty, value); }
        }
 
        /// <summary>
        /// Identifies the Points dependency property.
        /// </summary>
        public static readonly DependencyProperty PointsProperty =
            DependencyProperty.Register(
                "Points",
                typeof(PointCollection),
                typeof(SplineSeries),
                null);
        #endregion public PointCollection Points
 
        #region public PathGeometry SplinePoints
        /// <summary>
        /// Gets the collection of points that make up the line.
        /// </summary>
        public PathGeometry SplinePoints
        {
            get { return GetValue(SplinePointsProperty) as PathGeometry; }
            private set { SetValue(SplinePointsProperty, value); }
        }
 
        /// <summary>
        /// Identifies the SplinePoints dependency property.
        /// </summary>
        public static readonly DependencyProperty SplinePointsProperty =
            DependencyProperty.Register(
                "SplinePoints",
                typeof(PathGeometry),
                typeof(SplineSeries),
                null);
        #endregion public PathGeometry SplinePoints
 
        #region public double SplineTension
 
        /// <summary>
        /// Gets or sets the tension in the beziers that make up the spline.
        /// </summary>
        /// <remarks>
        /// The greater the tension, the more straight/linear the spline will look.
        /// Less tension creates a more curvy spline.
        /// </remarks>
        public double SplineTension
        {
            get { return (double) GetValue(SplineTensionProperty); }
            set { SetValue(SplineTensionProperty, value); }
        }
 
        /// <summary>
        /// Identifies the SplineTension dependency property.
        /// </summary>
        public static readonly DependencyProperty SplineTensionProperty =
            DependencyProperty.Register(
                "SplineTension",
                typeof(double),
                typeof(SplineSeries),
                new PropertyMetadata(2.5));
        #endregion public double SplineTension
 
        #region public Style PathStyle
        /// <summary>
        /// Gets or sets the style of the Path object that follows the data 
        /// points.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Path", Justification = "Matches System.Windows.Shapes.Path.")]
        public Style PathStyle
        {
            get { return GetValue(PathStyleProperty) as Style; }
            set { SetValue(PathStyleProperty, value); }
        }
 
        /// <summary>
        /// Identifies the PathStyle dependency property.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Path", Justification = "Matches System.Windows.Shapes.Path.")]
        public static readonly DependencyProperty PathStyleProperty =
            DependencyProperty.Register(
                "PathStyle",
                typeof(Style),
                typeof(SplineSeries),
                null);
        #endregion public Style PathStyle
 
#if !SILVERLIGHT
        /// <summary>
        /// Initializes the static members of the LineSeries class.
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", Justification = "Dependency properties are initialized in-line.")]
        static SplineSeries()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(SplineSeries), new FrameworkPropertyMetadata(typeof(SplineSeries)));
        }
 
#endif
        /// <summary>
        /// Initializes a new instance of the LineSeries class.
        /// </summary>
        public SplineSeries()
        {
#if SILVERLIGHT
            this.DefaultStyleKey = typeof(SplineSeries);
#endif
        }
 
        /// <summary>
        /// Acquire a horizontal linear axis and a vertical linear axis.
        /// </summary>
        /// <param name="firstDataPoint">The first data point.</param>
        protected override void GetAxes(DataPoint firstDataPoint)
        {
            GetAxes(
                firstDataPoint,
                (axis) => axis.Orientation == AxisOrientation.X,
                () =>
                {
                    IAxis axis = CreateRangeAxisFromData(firstDataPoint.IndependentValue);
                    if (axis == null)
                    {
                        axis = new CategoryAxis();
                    }
                    axis.Orientation = AxisOrientation.X;
                    return axis;
                },
                (axis) => axis.Orientation == AxisOrientation.Y && axis is IRangeAxis,
                () =>
                {
                    DisplayAxis axis = (DisplayAxis)CreateRangeAxisFromData(firstDataPoint.DependentValue);
                    if (axis == null)
                    {
                        throw new InvalidOperationException(Properties.Resources.DataPointSeriesWithAxes_NoSuitableAxisAvailableForPlottingDependentValue);
                    }
                    axis.ShowGridLines = true;
                    axis.Orientation = AxisOrientation.Y;
                    return axis;
                });
        }
 
        /// <summary>
        /// Updates the Series shape object from a collection of Points.
        /// </summary>
        /// <param name="points">Collection of Points.</param>
        protected override void UpdateShapeFromPoints(IEnumerable<Point> points)
        {
            if (points.Any())
            {
                PointCollection pointCollection = new PointCollection();
                foreach (Point point in points)
                {
                    pointCollection.Add(point);
                }
 
                //At least two points are necessary to generate a proper spline
                if (pointCollection.Count >= 2)
                {
                    PathGeometry geometry = new PathGeometry();
                    PathFigure figure = new PathFigure();
 
                    PointCollection bezierPoints = GetBezierPoints(pointCollection);
 
                    figure.StartPoint = bezierPoints[0];
                    for (int i = 1; i < bezierPoints.Count; i += 3)
                    {
                        figure.Segments.Add(new BezierSegment()
                            {
                                Point1 = bezierPoints[i],
                                Point2 = bezierPoints[i + 1],
                                Point3 = bezierPoints[i + 2]
                            });
                    }
 
                    geometry.Figures.Add(figure);
                    SplinePoints = geometry;
                }
                else
                {
                    SplinePoints = null;
                }
 
                Points = pointCollection;
            }
            else
            {
                Points = null;
                SplinePoints = null;
            }
        }
 
        #region Bezier Curve Building
 
        /*
         * Formulas and code pulled from Kerem Kat's MapBezier example:
         * http://www.codeproject.com/KB/silverlight/MapBezier.aspx
         */ 
 
        private PointCollection GetBezierPoints(PointCollection pts)
        {
            PointCollection ret = new PointCollection();
 
            for (int i = 0; i < pts.Count; i++)
            {
                // for first point append as is.
                if (i == 0)
                {
                    ret.Add(pts[0]);
                    continue;
                }
 
                // for each point except first and last get B1, B2. next point. 
                // Last point do not have a next point.
                ret.Add(GetB1(pts, i - 1, SplineTension));
                ret.Add(GetB2(pts, i - 1, SplineTension));
                ret.Add(pts[i]);
            }
 
            return ret;
        }
 
        private Point GetB1(PointCollection pts, int i, double a)
        {
            Point  derivedPoint = GetDerivative(pts, i, a);
            return new Point(pts[i].X + derivedPoint.X / 3, pts[i].Y + derivedPoint.Y / 3);
        }
 
        private Point GetB2(PointCollection pts, int i, double a)
        {
            Point derivedPoint = GetDerivative(pts, i+1, a);
            return new Point(pts[i + 1].X - derivedPoint.X / 3, pts[i + 1].Y - derivedPoint.Y / 3);
        }
 
        private Point GetDerivative(PointCollection pts, int i, double a)
        {
            if (pts.Count < 2)
                throw new ArgumentOutOfRangeException("pts", "Data must contain at least two points.");
  
            if (i == 0)
            {
                // First point.
                return new Point((pts[1].X - pts[0].X) / a, (pts[1].Y - pts[0].Y) / a);
            }
            if (i == pts.Count - 1)
            {
                // Last point.
                return new Point((pts[i].X - pts[i - 1].X) / a, (pts[i].Y - pts[i - 1].Y) / a);
            }
  
            return new Point((pts[i + 1].X - pts[i - 1].X) / a, (pts[i + 1].Y - pts[i - 1].Y) / a);
        }
        #endregion
    }
}
 
#endif



Note that I borrowed my Spline/Bezier code from Kerem Kat's example: http://www.codeproject.com/KB/silverlight/MapBezier.aspx

Essentially what it does, is takes prior points to adjust such that they curve into the next. The UpdateShapeFromPoints method was changed from the standard LineSeries and uses all of the helper methods that were added to calculate a Bezier curve.

We're pretty much almost done, except for one more minor touch. We need to have the default style included, such that it complies with how Silverlight Toolkit handles it's control templating. We add the following chunk of code to Themes\generic.xaml of the same project:


    <!--  charting:SplineSeries  -->
    <Style TargetType="charting:SplineSeries">
        <Setter Property="IsTabStop" Value="False" />
        <Setter Property="PathStyle">
            <Setter.Value>
                <Style TargetType="Path">
                    <Setter Property="StrokeThickness" Value="2" />
                    <Setter Property="StrokeMiterLimit" Value="1" />
                </Style>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="charting:SplineSeries">
                    <Canvas x:Name="PlotArea">
                        <Path Data="{TemplateBinding SplinePoints}" Stroke="{TemplateBinding Background}" Style="{TemplateBinding PathStyle}"/>
                        <Polyline Points="{TemplateBinding Points}" />
                    </Canvas>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Now, just recompile the Toolkit and you should be good to go!

I've included a "patch" with these files and their updates -- they should be capable of being pasted over their old versions (the Themes\generic.xaml just has the SplineSeries.xaml pasted into it -- I would strongly recommend you doing this with your own source):

https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=0B9hGvs6yJgfJNzA4YmE1OTctNzNmYy00MzMzLWJhNDQtNTc0M2FlNTA3NzFm&hl=en_US