Compiler Error 128

Many things cause compiler error 128. Ref, here.

Sometimes reregistering aspnet with iis works.

In my case, I had attached a console to a running asp.net app. Then I uploaded the correct release build over the top of that (the release build doesn’t attach a console) and then I got compiler error 128. It cleared up on iisreset. If in doubt, pull the power out.

Getting WCF to talk ordinary HTTP to a browser

This is an exercise in driving nails into the coffee table with your shoe. The goal isn’t really all that obviously beneficial and the tool isn’t the expected tool for the job. WCF wants to speak SOAP to SOAP aware clients. With the expansion to support a REST API with System.ServiceModel.Web, you can get a WCF service to talk to a browser. HOWEVER

* The browser doesn’t serialize complex objects to a C# like data type system on Request or Response. Instead you deal primarily in a raw Stream.
* Some browsers don’t speak XHTML (they will render it if you call it text/html, but MSIE will render xhtml/application as XML), so you can’t just return an X(HT)ML payload.
* WCF used this way is a “bring your own view engine” framework. I chose SharpDom for this exercise. It seems like it should be possible to support returning a SharpDom return value that serializes to XHTML with a type of text/html, but I don’t know how to do that.
* MVC already solves a lot of similar problems.

BUT with WCF you get some of those WCF features, like umm, well, when you have a browser client a lot of features aren’t avail (e.g. fancy transaction support, callbacks, etc), but you can still do fancy thinks like instancing, and supporting a HTML browser, JSON and WCF interface all on top of mostly the same code.

Just serving a page is fairly easy. Turn on web support in the config (same as any REST enabling, see end of post),

[WebGet]
public Stream HomePage(){ 
            //Return a stream with HTML
            //... I have skipped the view engine, I used SharpDom
            MemoryStream stream = new MemoryStream();
            TextWriter writer = new StreamWriter(stream, Encoding.UTF8);
            new PageBuilder().Render(model, writer);
            writer.Flush();
            stream.Position = 0;
            return stream;
}


What will the URL look like? Well in devepment in Win 7, if you don’t have admin rights, it will be something like:

http://localhost:8732/Design_Time_Addresses/HelloWorld/web/HomePage

The http://localhost:8732/Design_Time_Addresses/ is the address that a non-admin can register. It looks like you can’t register 8080.

The /web/ part is because in my endpoints in config (below), the endpoint is “web”

Also notice you have to set an encoding (and I suppose you’ll want that to match what the HTML meta tag says)

[WebInvoke(Method = "POST")]
public Stream AnotherPostBack(Stream streamOfData)
{
StreamReader reader = new StreamReader(streamOfData);
String res = reader.ReadToEnd();
NameValueCollection coll = HttpUtility.ParseQueryString(res);
//Return a stream of HTML
}

To invoke the above, use an METHOD of POST and an action of

http://localhost:8732/Design_Time_Addresses/HelloWorld/web/AnotherPostBack

And finally, use a web friendly host in your console app

using (WebServiceHost host = new WebServiceHost(typeof(HelloService)))
{
host.Open();
Console.ReadLine();
}

http://stackoverflow.com/questions/1850293/wcf-rest-where-is-the-request-data

Also, you can post back to this kind of operator… but for the life of me I can’t figure out how to get the Content. I can see the headers, I can see the content length, but I can’t get at the stream that holds the post’s content.

(This StackOverflow Q & A implies that to get the raw content, you have to use reflection to inspect private variables: )

[OperationContract(Action = "POST", ReplyAction = "*")]
[WebInvoke(Method = "POST")]
public Stream PostBack(Message request)
{
}

Obviously, cookies and URL params are just a matter of inspecting the IncomingRequest.

And the config:

<system.serviceModel>
    <services>
      <service name="WcfForHtml.HelloService" behaviorConfiguration="TestServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8732/Design_Time_Addresses/HelloWorld"/>
          </baseAddresses>
        </host>
        <endpoint address="web"
                  binding="webHttpBinding"
                  contract="WcfForHtml.HelloService"
                  behaviorConfiguration="webBehavior">
        </endpoint>
      </service>
    </services>
      <behaviors>
        <!--SERVICE behavior-->
        <serviceBehaviors>
          <behavior name="TestServiceBehavior">
            <serviceMetadata httpGetEnabled="true" />
            <serviceDebug includeExceptionDetailInFaults="true"/>
          </behavior>
        </serviceBehaviors>
        <!--END POINT behavior-->
        <endpointBehaviors>
          <behavior name="webBehavior">
            <webHttp/>    
          </behavior>
        </endpointBehaviors>
      </behaviors>
  </system.serviceModel>

Posted in wcf

Production Trace

Assume you work in a large organization, you write code, you really would like to see some diagnostic trace from your app in Test, Staging or Production, but a server admin owns all of them. You can’t have the event logs, remote desktop access, or ask that the web.config be edited to add or a remove a System.Diagnostics section. Just imagine.

Production trace needs to be:
- high performing, if it slows down the app, which may already be under load, not good.
- secure, since trace exposes internals, it should have some authorization restrictions
- not require change of code or config files, because large organizations often have paralyzing change management processes
- support a variety of listeners that will meet the requirements above (and if those listeners are write only, then a reader will need to be written)

System.Diagnostics -File-
- Perf- Not very performant, will likely have contention for the file.

System.Diagnostics-Console, DebugString, Windows Event Log
- You can’t see it. End of story.

ASP.NET Trace.axd and In Page
- Perf- not so good.
- Security- it’s well known, so security teams often disable it
- Config- Can sort of enable on a by page/by user basis if you use a master page or base page to check rights and maybe a query string.

Custom Session Listener
Write to session.
- Okay for single user trace. Need a page to dump the results.
- Perf probably okay, could hog memory.
- Security, pretty good, by default you can only see your own stuff.

Custom Cache Listener
- Write trace to cache
- Will have locking problems
- Won’t hog memory because of cache eviction
- Cache eviction could remove trace too fast.

HttpContext.Items listener +Base page to dump contents at end of request
- Only shows one page of trace at a time
- Probably high perf.
- Won’t show other users