WCF issues - line not reached - c#

I have a WCF service library, name ServerWCF, which contains a "AdminService" service. One of the methods of this service is List LoadStation() which should return a List of train stations from my database.
I also have a WPF Client, and I'm using a dropdown that should contain the Cities of the stations. When I added the Service Reference in the client, named AdminServiceReference, i noticed that the signature of the method is Station[] Load Station() instead on ListLoadStation(). I don't know if I can do anything about this as the code is generated automatically in the client, but whatever(I used the resharper refactoring suggestion, but didn't make any difference). The problem is that on the below code, the foreach line is never accessed. I placed a breakpoint on the line above, I stepped into and noticed that the list returned by the Server contains all of the station, which is a good thing, but after i step out and step over, the program is not going to the foreach that populates the dropdown, but returns to the second line, which is the reason why, obviously, my dropdown remains empty, lonely and sad :( Any tip on how can i sort this out? PS: that same code worked fine when my list was a ArrayList and was containing only Cities, but I need all the objects.
Client code:
private void fromStationCB_DropDownOpened(object sender, EventArgs e)
{
var adminProxy = new AdminServiceClient();
fromStationCB.Items.Clear();
var list = adminProxy.LoadStations();
foreach (var items in list)
fromStationCB.Items.Add(items.City);
label5.Content = "";
}
Server code:
public List<Station> LoadStations()
{
List<Station> list = new List<Station>();
using (var context = new RailwaySystemModelContainer())
{
/*foreach (var station in context.Stations)
list.Add(station);*/
list.AddRange(context.Stations);
return list;
}
}

I had some problems when using list as a return type. It was something different, but you can try change the return type of LoadStations to an array of Station. Also try delete your reference, build the server side code and then add the reference again. You can have some mismatch. Also Station should be marked as a DataContract and its properties as DataMember to successfully pass it via service.

Related

How to find a type by FQN in a solution?

I am writing a Rider/ReSharper nav-from-here plugin which is supposed to determine a target type based on a symbol I am standing on using some simple rules, and finally, navigate to it.
The first part is okay, I have managed to form the FQN needed, but I am struggling with the navigation. I found this StackOverflow post, and thought I might try this approach. So I have been trying to use TypeFactory.CreateTypeByCLRName for like two hours to create an IDeclaredType instance to be able to get the IDeclaredElement using GetTypeElement() and eventually get its declarations. But the API seems to have changed and no matter what I do I cannot get my code to work.
Here is what I've got so far:
// does not work with Modules.GetModules(), either
foreach (var psiModule in solution.GetPsiServices().Modules.GetSourceModules())
{
var type = TypeFactory.CreateTypeByCLRName("MyNamespace.MyClassName", psiModule);
var typeElement = type.GetTypeElement();
if (typeElement != null)
{
MessageBox.ShowInfo(psiModule.Name); // to make sure sth is happening
break;
}
}
The weird part is, I actually see a message box - but only when the tab with MyClassName.cs is active. When it is in focus, everything is fine. When it's not or the file is closed, the class does not get resolved, type.IsResolved is false.
What am I doing wrong?
To do this, you should have a IPsiModule instance from the context where you plan to use the type you're looking for. You can get it from some syntax node you're working with via .GetPsiModule() method or via many other ways (like dataContext.GetData(PsiDataConstants.SOURCE_FILE)?.GetPsiModule().
void FindTypes(string fullTypeName, IPsiModule psiModule)
{
// access the symbol cache where all the solution types are stored
var symbolCache = psiModule.GetPsiServices().Symbols;
// get a view on that cache from specific IPsiModule, include all referenced assemblies
var symbolScope = symbolCache.GetSymbolScope(psiModule, withReferences: true, caseSensitive: true);
// or use this to search through all of the solution types
// var symbolScope = symbolCache.GetSymbolScope(LibrarySymbolScope.FULL, caseSensitive: true);
// request all the type symbols with the specified full type name
foreach (var typeElement in symbolScope.GetTypeElementsByCLRName(fullTypeName))
{
// ...
}
}

MVC create function does not add created track to list

I have a problem with my MVC application. The application is about a tracklist where there is a function called create track.
I have created a dataprovider class which adds dummy data to a list. Then the list gets show on the page. The list itself works and it show the dummy data. Now i have created a create action in my controller like this:
public ActionResult Create(FormCollection collection)
{
try
{
// TODO: Add insert logic here
int hours = int.Parse(collection["Hours"]);
int minutes = int.Parse(collection["Minutes"]);
int seconds = int.Parse(collection["Seconds"]);
Track track = new Track();
track.Name = collection["Name"];
track.Artist = collection["Artist"];
track.AlbumSource = collection["AlbumSource"];
track.length = new AudioDevices.Time(hours, minutes, seconds);
track.Style = (Category)Enum.Parse(typeof(Category), collection["style"]);
trackList.Add(track);
return RedirectToAction("Index");
}
catch
{
return View();
}
}
Now... When i start my application I click create. There i enter information for my track and click save. Now when it saves i go back to my list of tracks, but the track doesnt get added to my list.
My Visual Studio shows that the code has handled 2 requests without any errors. It just doesnt get added to the list.
I understand that i am not working with a database and i dont want to work with a database since its not needed in this excercise. I understand that the track will dissapear after restarting the program.
I have instantiaded the tracklist like this at the end of my trackcontroller.cs:
private static List<Track> trackList;
public TrackController()
{
if(trackList == null)
{
trackList = DataProvider.GenerateDefaultTracks();
}
}
If your code follows the standard pattern, every time your Create function is called in the controller, a new controller is created. If your object trackList is created in the constructor, then a fresh one will be created for each call to Create giving the impression that nothing has happened.
Your data is stored in a variable. This variable is not public so it is not obtainable for the view unless you pass it along.
I suggest you store the tracklist in the ViewBag. this way it's accessible from the view.
Now I do not know how you implemented the tracklist so I will just give an example.
define when the page is created.
ViewBag.tracklist = new List<Track>();
after creating the track you put it in the viewbag like this:
ViewBag.trackList.Add(track);
You can access this data in the view or pass it along in the action index parameters like:
return View(ViewBag.tracklist);
I have never actually closed this, but it turned out my visual studio was corrupt. Everything worked fine as i did not received any erros. Reinstalling visual studio worked out.

Connecting to mongodb sing C# quick tour not creating db or collection

I'm going through the mongoDB Driver Documentation Quick Tour for the first time. Specifically the 2.4 version.
I've created a fresh mongodb instance at the 192.168.1.50 address, and it appears to be running correctly.
The MongoDB documentation gives the following example:
var client = new MongoClient("mongodb://192.168.1.50:27017");
#It's ok if the database doesn't yet exist. It will be created upon first use
var database = client.GetDatabase("testDB");
#It’s ok if the collection doesn’t yet exist. It will be created upon first use.
var collection = database.GetCollection<BsonDocument>("testCollection");
However, when I go on my server, and I enter the mongo console
mongo
And I list the databases using
show dbs
The output is only
admin 0.000GB
local 0.000GB
Is there anything else I should have done to make this work? I'm getting no errors on try/catch, and it appears to be running fine.
Troubleshooting
So far I've confirmed that mongodb is running by using the following:
netstat -plntu
Shows mongod running on 27017 in the LISTEN state.
I'd also be interested in knowing if there's a way on the mongodb server to view live connections, so I could see if it were actually successfully connecting.
Well the problem is that you need to create almost one collection in order to persist the created database (weird right?) i tested it with robomongo and works in that way.
The problem is that GetCollection method is not creating the target collection, you can try with this code:
static void Main(string[] args)
{
var client = new MongoClient("mongodb://192.168.1.50:27017");
//# It's ok if the database doesn't yet exist. It will be created upon first use
var database = client.GetDatabase("test");
//# It’s ok if the collection doesn’t yet exist. It will be created upon first use.
string targetCollection = "testCollection";
bool alreadyExists = database.ListCollections().ToList().Any(x => x.GetElement("name").Value.ToString() == targetCollection);
if (!alreadyExists)
{
database.CreateCollection(targetCollection);
}
var collection = database.GetCollection<BsonDocument>(targetCollection);
}
It turns out that a method I had found on how to set multiple bindIp's was incorrect. The problem wasn't with the C# at all. I found the solution here
In case that ever goes away, here's the current settings I had to follow for multiple ip's
edit file /etc/mongod.conf
Wrap the comma-separated-Ips with brackets
bindIp = [127.0.0.1, 192.168.184.155, 96.88.169.145]
My original code worked fine, I just didn't have the brackets on the bindIp.

How return List<string>[] in a web service method

I want to return List<string>[] in a web service and use that return in a windows form like below :
[WebMethod]
public List<string>[] MyMethod()
{
...
...
List<string>[] list_ar = new List<string>[]{list_optgroup, list_option, list_optgroup_option};
return list_ar;
}
but on the windows form side I should get that return value like this :
MyService_Soft service = new MyService_Soft();
string[][] str_ar = service.MyMethod();
What is going on and how can I get that List<string>[] on the windows form side?
Also it seems like I have an error in these lines :
MyService_Soft service = new MyService_Soft();
string[][] str_ar = service.FillComboBoxes();
Error :
Unable to automatically step into the server. Connecting to the server
machine 'blablabla' failed.unknown user name or bad password...
What does this error mean and how can I figure out what line in that web service causes this error?
I see no bad errors. You can't debug 2 processes simultaneously from one debugging process. Since server code is running in separate process, you can't step-into it.
To debug server code, open another instance of MS Visual studio (or whatever IDE you use) with server project source code, and go to menu Debug -> Attach to process, then find your server service hosting process and click "Attach".
As for returning string[][] instead of List[] - it is also expected behaviour as client application doesn't know the type of returned collection - the proxy class is autogenerated based on WSDL file. Actually you can change it to use List<> instead of array. Considering WCF service, open WCF SErvice reference properties and select the type of collections (by default array, but can be changed to List in you desire).
But I see no reasons to require to get List instead of array. The only difference is that List is mutable. You shouldn't logically want to have ability to change the returned collection! You'd better create a new collection, based on the returned array and modify it instead.
UPDATE: Code request.
The code for the last and main recommendation is really very straight forward:
public List<string>[] SomeClientBuilsenessLogicMethod()
{
var serviceClient = GetServiceClientInstance(); //you might want to have single instance (single connection) of WCF service client, so I implemented it's creation as factory method here.
string[][] serviceData = serviceClient.MyMethod();
List<string>[] mutableDataList = serviceData.Select(x=>x.ToList()).ToArray();//Not the best memory usage here probably (better is a loop), but for not big data lists it's fine.
//Perform any needed operations for list changing. Again there is NO NEED to use List if you don't plan to add/remove items to/from that collection.
return mutableDataList;
}

WCF RIA service return data not matching on the 2 sides of the service

I originally thought this was a INotifyPropertyChanged/Binding issue because I'm not sure how to debug the silverlight part. So I had to put a messagebox in a foreach loop and view the values after the data returned that way. It turns out that I'm having trouble getting the updated data from the service. I use the service to do some updates to data on the server and when it gets back call to reload the data. This part of the service is returning the correct data (I verified using a breakpoint so I could look at the data result was holding). But the silverlight side is not getting the right data. Here is the relevant code.
public IQueryable<OurClass> GetItems(string condition)
{
var result = from items in context.OurClass
where item.value == condition
select item;
return result; //had my breakpoint here and the values were the correct updated values
}
/
Context.Load<OurClass>(Context.GetItemsQuery(condition)).Completed += new EventHandler(Context_LoadCompleted);
/
private void Context_LoadCompleted(object sender, EventArgs e)
{
IEnumerable<OurClass> result = ((LoadOperation<OurClass>)sender).Entities;
//This is where I put a MessageBox to view the returned results and the data was different
//than what was contained in the other result
}
Any ideas what could cause this? What should I look at next?
EDIT:
Some example data is OurClass.OurProperty will equal "Test" on the server side but once it is received on the client it will equal "Development" which was the old value. The IEnumerable will hold the newly added records and not have the deleted ones. Any that previously existed will contain the old property values and not the new values.
The solution was that I needed to add the parameter LoadBehavior.RefreshCurrent to the query call. So this:
Context.Load<OurClass>(Context.GetItemsQuery(condition)).Completed += new EventHandler(Context_LoadCompleted);
Needed to be this:
Context.Load<OurClass>(Context.GetItemsQuery(condition), LoadBehavior.RefreshCurrent, true).Completed += new EventHandler(Context_LoadCompleted);
How is the data different on each side of the service? can you show us some example data. You can have a look at data using something like wireshark (will need to be on the server, or on your client where you are running your silverlight applet from.)
Have you tried debugging your silverlight properly, ie attach to the process as shown here: http://www.michaelsnow.com/2010/04/22/silverlight-tip-of-the-day-2-attach-to-process-debugging/
I would also recommend turning on WCF tracing as detailed here: http://msdn.microsoft.com/en-us/library/ms733025.aspx

Categories