Saturday, May 22, 2010

Configuring mexConnections with net.tcp binding

This is one of the issues that does not explain it self to me and I could not find any help from MSDN, so I thought of sharing in the blog for future use.

I have a WCF library that is hosted in IIS, after some time we wanted to increase the max connection property of the service to 100 from the default value of 10 and also change the listenBackLog value to the same (if you dont know what these attributes do, a googling would help :0)



The service was configured with 2 endpoints, a net;tcp endpoint and the the other being the meta data exchange endpoint using mexTcpBinding.
I also configured a base address, part of the configuration file looks like this :


Host it in IIS 7 and the service does not start at all and throws up an error like this :

There is no compatible TransportManager found for URI 'net.tcp://ct-svr:8731/AuthorisationManager/Services.Security.AuthorisationManager.svc/mex'. This may be because that you have used an absolute address which points outside of the virtual application, or the binding settings of the endpoint do not match those that have been set by other services or endpoints. Note that all bindings for the same protocol should have same settings in the same application.

So, I removed the mex endpoint and it worked, but I wanted to keep the mex endpoint so after some googling and hard luck the solution was to expose the metadata through http, now the configuration file looks like this.



well, this works fine, but I still won't to know why the earlier piece of config did not work, if any ones has any idea, just put up a comment.




Monday, May 10, 2010

Response.Redirect vs PostBackUrl

I normally use Response.Redirect to navigate from page to page, someone told me the other day that it would be better to use PostBackUrl of a control to redirect to a page then use Response.Redirect.

So, I ran a little test of my own, created a 2 sample pages, where on a button click I do a Response.Redirect like this.

protected void Button1_Click(object sender, EventArgs e)
{
Response.Redirect("Advance.aspx");
}

Next I ran Fiddler, this is the result I got on the button click, the response I get back from the server is not the content of the page I want but this...

HTTP/1.1 302 Found
Server: ASP.NET Development Server/10.0.0.0
Date: Mon, 10 May 2010 16:17:57 GMT
X-AspNet-Version: 4.0.30319
Location: /Advance.aspx
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 130
Connection: Close

Object moved to here.

Here; point to the page you want to navigate to (have to live with this HTML formating :))

The server issues a 302 and the browser issues another request to the actual page I want, so we got 2 round trips to the server.

Next< I set the PostBackUrl property of the button, and now if i see the page source, I see a javascript redirect, and if I take a look at Fiddler, on the button click, I see that there is a POST request going to the server. Now, the server returns me the page I want in just one round trip. The other advantage I get is that I can access the state of the previous page by using the PreviousPage property, all i need is to cast the return type of this property to the type of the previous page. I can access the control state from this, however you want be able to access the ViewState of the previous page from this property, but you can expose the needed view state key/value through a public property of the previous page. You can also set the %@PreviousPageType directive like this

now, you would be able to access the previous page through the PreviousPage property without having to cast into the type of the previous page.

So, in summary, use the PostBackUrl when ever you can over Response.Redirect
You would only be able to use this property with controls that implement the IButtonControl interface.

Sunday, May 2, 2010

Passing in parameters into OPENQUERY

I was struggling for some time now, trying to pass in parameters into OPENQUERY, OPENQUERY does not support passing in parameters, all it does it takes a string value as the 2nd parameter like this,

SELECT * FROM OPENQUERY(LINKSERVER_NAME, 'SELECT * FROM COUNTRY WHERE COUNTRYID = 10')

What's worse, it does not support passing in a varchar variable as the 2nd parameter.

So, if you want to pass in parameters, then one of your option is creating a dynamic query and executing it like this

declare @var int = 10
declare @query varchar(max) =
'select * from openquery(Test_link,' + ''''
+ 'SELECT * FROM dbo.TEMP where ID > ' + CAST(@var AS VARCHAR(MAX))
+ '''' + ')'


execute(@query)


IF you want to use the result returned by OPENQUERY, like for an example for joining to another source table, you would have to create a table variable, populate your result and start joining, and illustration would be like this (hypothetical example);

declare @var int = 10
declare @query varchar(max) =
'select * from openquery(Test_link,' + ''''
+ 'SELECT * FROM dbo.TEMP where ID > ' + CAST(@var AS VARCHAR(MAX))
+ '''' + ')'

declare @table Table( id int, name varchar(max))

insert into @table
execute(@query)

select * from @table r
inner join temp t
on r.id = t.ID
where r.name = 'M';

But I would like a better way to do this, for 3 reasons
1) I am executing dynamic queries, so my performance is not what I want.
2) Results returned by OPENQUERY can be joined to another source, but with the method show above, I have to opt to a table variable.
3) Inefficient string concatenations.

Any better solution to this?