Question

I am working on a web application in silverlight. I have overloaded the WebClient.GetWebRequest method as given below:-

public class WebClientWithCookies : WebClient
    {
        [SecurityCritical]
        protected override WebRequest GetWebRequest(Uri address)
        {
            string cookieContent = HtmlPage.Document.Cookies;

            WebRequest request = base.GetWebRequest(address);
            HttpWebRequest webRequest = request as HttpWebRequest;
            if (webRequest != null && cookieContent != null && cookieContent != string.Empty)
            {
                CookieContainer cookieContainer = new CookieContainer();
                cookieContainer.Add(address, new Cookie() { Value = HtmlPage.Document.Cookies });
                webRequest.CookieContainer = cookieContainer;
            }
            return request;
        }
    }

But I am getting the following exception:

System.TypeInitializationException was unhandled by user code
Message=The type initializer for 'SigmaWC.Utility.RestCommunicator' threw an exception. TypeName=SigmaWC.Utility.RestCommunicator
StackTrace: at SigmaWC.Utility.RestCommunicator..ctor() at SigmaWC.App..ctor() InnerException: System.TypeLoadException Message=Inheritance security rules violated while overriding member: 'SigmaWC.Utility.WebClientWithCookies..ctor()'. Security accessibility of the overriding method must match the security accessibility of the method being overriden. StackTrace: at SigmaWC.Utility.RestCommunicator..cctor() InnerException:

Can anyone help in how to elevate the security settings in silverlight.

Was it helpful?

Solution

Documentation about this is scarce to say the least. However, there are a couple of resources which are useful:

MSDN Indicates that you cannot use framework members with a SecurityCriticalAttribute.

Types and members that have the SecurityCriticalAttribute cannot be used by Silverlight application code. Security-critical types and members can be used only by trusted code in the .NET Framework for Silverlight class library.

In the case of WebClient, the GetWebRequest method does not have this attribute, however the constructor does.

This MSDN Security blog Implies that if the default constructor has any Security attribute, the class cannot be used for inheritance in a Silverlight client.

Further to that, the aforementioned MSDN blog implies that Security attributes are ignored in Silverlight assemblies which are not part of the core framework. This may however only apply to Assembly level attributes.

Anyway, to cut a long story short. You cannot derive from WebClient because of the SecuritySafeAttribute on the constructor. To illustrate the point, this also causes an exception at runtime:

public class MyWebClient : WebClient
{

}

The alternative is to roll your own WebClient. It takes a little work, but the following example does work with the following handler:

public class MyHandler : IHttpHandler
{

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        context.Response.Write("Hello World");
        foreach (Cookie cookie in context.Response.Cookies)
        {
            //Cookies from the client - there will be 1 in this case
        }
    }

...

public class MyWebClient
{
    public MyWebClient()
    {

    }

    public void InvokeWebRequest(Uri address)
    {
        //Set the cookie you want to use.
        string cookieContent = "I like cookies";

        // Register a http client - without this the following webRequest.CookieContainer setter will throw an exception
        WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);

        //This bit you know, but dont forget to set Name on your new Cookie.
        HttpWebRequest webRequest = WebRequest.Create(address.AbsoluteUri) as HttpWebRequest;
        if (webRequest != null && !String.IsNullOrWhiteSpace(cookieContent))
        {
            webRequest.CookieContainer = new CookieContainer();
            webRequest.CookieContainer.Add(address, new Cookie() { Value = cookieContent, Name = "MyCookie" });
        }

        //Invoke the async GetResponse method.
        webRequest.BeginGetResponse(o =>
            {
                HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(o);
                using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                {
                    //Read the result
                    string result = reader.ReadToEnd();
                }

                foreach (Cookie cookie in response.Cookies)
                {
                    //The cookies returned from the server.
                }
            }, null);

    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top