2011年9月22日

[WCF] Passing & Retrieving message header in basicHttpBinding Services

To send message properties to the server.


  1: var svc = new GPServiceFactory().GetInboxService();
  2: using (new OperationContextScope(((IClientChannel)svc))) {
  3:  OperationContext oc = OperationContext.Current;
  4:  HttpRequestMessageProperty httpRequestProperty = null;
  5:   if (oc.OutgoingMessageProperties.ContainsKey(HttpRequestMessageProperty.Name)) {
  6:   httpRequestProperty =
  7:    oc.OutgoingMessageProperties[HttpRequestMessageProperty.Name]
  8:      as HttpRequestMessageProperty;
  9:    }
 10: 
 11:    if (httpRequestProperty == null) {
 12:     httpRequestProperty = new HttpRequestMessageProperty();        
 13:    }
 14:    httpRequestProperty.Headers.Add("ClientTimeZone", param["TimeZone"]);
 15:    oc.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
 16:    return svc.GetWorkitemsInQueue(appId, UserId, queueName, 1000, 1);
 17: }

 


To retrieve properties

  1: Dictionary<String, String> param = null;
  2: try {
  3:  if (OperationContext.Current.IncomingMessageProperties.Keys != null) {
  4:   param = new Dictionary<string, string>();
  5:    foreach (var key in (OperationContext.Current.IncomingMessageProperties.Keys)) {
  6:     if (System.ServiceModel.OperationContext.Current.IncomingMessageProperties[key] is HttpRequestMessageProperty) {
  7:      var p = OperationContext.Current.IncomingMessageProperties[key] as HttpRequestMessageProperty;
  8:       foreach (string k in p.Headers.AllKeys) {
  9:        if (k.Equals("timezone", StringComparison.OrdinalIgnoreCase)) {
 10:         string v = p.Headers[k].StartsWith("+") ? p.Headers[k].Substring(1) : p.Headers[k];
 11:         param.Add("TimeZone", v);
 12:        }
 13:        else {
 14:         param.Add(k, p.Headers[k]);
 15:        }
 16:      }
 17:    }
 18:  }
 19: }

2011年9月21日

[Entity Framework] Passing expressions thru methods

I want to have a “generic” entity method to does some routine tasks before actually query to the database, and I want this method to accept a Func<T,bool> as input paramater. So I wrote codes like this…

 

protected static TM_STD_APPLYFORM_DATA QueryApplyFormDataFunc<TM_STD_APPLYFORM_DATA, bool> where) {
using (var db = new DBEntities()) {
var table = db.TM_STD_APPLYFORM_DATA.Where(where);
return table.SingleOrDefault();
}
}



After some tests, I realized that this function seems to have returns whole data in that table and does a “In memory” filter hence lead to poor performance. Solution is pretty easy, since Linq to Entity cannot generate correct SQL, the only thing we need to do is to make it know exactally what we want. So simply change the input paramter type to Expressions<Func<T,bool>> like this.



 




protected TM_STD_APPLYFORM_DATA QueryApplyFormData(System.Linq.Expressions.Expression<Func<TM_STD_APPLYFORM_DATA, bool>> where, ) {
using(var db = new DBEntities()){
return db.TM_STD_APPLYFORM_DATA.Where(where).SingleOrDefault();
}
}

2011年9月2日

[Entity Framework]Unable to load the specified metadata resource

When developing DAL in Entity Framework in a web scenario, somehow I got this error at runtime. Digging into the message, I realized that there are configuration regarding EF metadata we should pay extra attentions on it.

In my case, I want to place all customized biz-logic handlers in %WebSite%\bin\BizLogic folder, and left system related files in <%WebSite%>\bin folder. In this case, we need to specify correct EF metadata path in our web.config file instead of using the defaults.

Say we have a DAL project called FormDesignEntities.

  • Open the project in VS2010, open edmx file, and open the Properties window.

1

  • Change the [Metadata Artifact Processing] property to [Copy to Output Directory]

image

  • Compile the project, you will find three files in the output folder; In my case, they are FormDesignEntities.csdl, FormDesignEntities.msl,FormDesignEntities.ssdl. These files contain database schemas and conceptual models.
  • Open consuming project, in my case, the Web project; right click on project root, then [Add Existing Item…]
  • Select those files and add them into the consuming project as a link

image

  • Compile and deploy the consuming project
  • Now open your web.config file, looking for connection strings, your connection string should look like this
<add name="FormDesingEntity"
 connectionString=
"metadata=~/bin/FormDesignEntities.csdl|~/bin/FormDesignEntities.ssdl|~/bin/FormDesignEntities.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=tw-bpmdb,3433;initial catalog=BPM_Platform_POC;persist security info=True;user id=sa;password=2wsx#EDC;multipleactiveresultsets=True;App=EntityFramework&quot;"
 providerName="System.Data.EntityClient" />



  • See there’re metadata file location settings in this setting, since we are in a web scenario, and I want to put these meta files in bin folder, we can use “~” to reference to web site folder and ~/bin to point to bin folder. Simply modify these path to fit requirements

Blog Archive

About Me