Request for Service Host UI change

Apr 3, 2013 at 9:39 PM
Edited Apr 3, 2013 at 9:49 PM
I am playing with the Service host to verify that my host service is working. The primary key for the test data (based on your examples) is a guid. If I double click on a service, chose an operation (say getAll) and then hit invoke, I see the data. This is cool. But when I try to select the GUID value so I can use that for a Get, it won't let me do so.

While I am sure I can work my way through the code to find the offending page, since this is (I believe) a standard part of the FW, would it be possible to have ^C or a right-click menu be enabled so I can select the GUID and paste it into the get invoke option.

This is not a big deal as I can always get the GUID from SQL manager. I just figured I would mention it so that, if someone there is hitting that code for some other reason, they could also enable copy (I can already select the tree node, just not copy it to the clipboard.)

Also, I have tried to use the JSON and XML buttons, but they do not seem to do anything. Have I left out code in my Host app, not turned on a switch somewhere, or something else?

Thanks!
Coordinator
Apr 8, 2013 at 6:47 PM
So this is in the harness where you click "invoke", or are we talking about the results window?

Markus
Apr 9, 2013 at 10:11 PM
Markus,

Yup, the tree view control. It would be nice to be able to select the ID (especially if GUIDs are used) so I can then do a test where I get a specific record.

Also, in the implementation I have, the invoke works just fine (other than not being able to select). But the Get XML and Get JSON don't seem to work. At least when I click them, all I get is either 2 braces (JSON) or an empty XML construct (it has the namespace info, etc., just no data.) But if I try to invoke the REST HTTP (JSON) service - it works and returns JSON. I am not sure if it is something I am doing or not but I seem to remember in the demo that when he clicked on it, it showed the data in the format specified by the button.

Thanks
Coordinator
Apr 9, 2013 at 11:26 PM
I see. I'll take a look at that.

The XML/JSON button will give you the request object in XML and JSON formats respectively. If the request is an empty object, then the XML/JSON is empty too. What does your request contract look like?

Markus
Apr 10, 2013 at 1:40 AM
Markus, Here are the key parts for GetAllEmployees. I have only included the code for the GetAllEmployees as all the others have the same issues. If I use the invoke option, I always get a treeView control with both employees in it. When I click on the XML button (before or after clicking on Invoke), I get the following: <GetAllEmployeesRequest xmlns="http://schemas.datacontract.org/2004/07/Employees.Services.Contracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"/> and with the JSON button: {} ``` public interface IEmployeesService { /// <summary> Retrieves a list of Employees</summary> /// <param name=""request""> GetAllEmployeesRequest</param> /// <returns>GetAllEmployeesResponse</returns> [OperationContract] GetAllEmployeesResponse GetAllEmployees(GetAllEmployeesRequest request); .... } [DataContract] public class GetAllEmployeesRequest { /// <summary>Constructor</summary> /// <remarks>Explicitly set default values for all /// properties in the constructor</remarks> public GetAllEmployeesRequest() { } } [DataContract] public class GetAllEmployeesResponse : GenericResponse { ///<summary>Constructor</summary> /// <remarks>Explicitly set default values for all properties /// in the constructor</remarks> public GetAllEmployeesResponse() : base() { Employees = new List<EmployeesQuickInformation>(); } /// <summary>Actual list of Employees </summary> [DataMember(IsRequired = true)] public List<EmployeesQuickInformation> Employees { get; set; } } // Note - GenericResponse simply has the Success and Failure properties and the base() call is to make sure they are initialized. [DataContract] public class EmployeesQuickInformation { /// <summary>Constructor</summary> /// <remarks>Explicitly set default values for all properties /// in the constructor</remarks> public EmployeesQuickInformation() { // Set all variables to their default value ID = Guid.Empty; FirstName = string.Empty; LastName = string.Empty; } [DataMember(IsRequired = true)] public Guid ID { get; set; } [DataMember(IsRequired = true)] public string FirstName { get; set; } [DataMember(IsRequired = true)] public string LastName { get; set; } } and [DataContract] public class EmployeesInformation { /// <summary>Constructor</summary> /// <remarks>Explicitly set default values for all properties /// in the constructor</remarks> public EmployeesInformation() { // Set all variables to their default value ID = Guid.Empty; FirstName = string.Empty; LastName = string.Empty; Sex = string.Empty; CompanyID = Guid.Empty; } // Now define all the fields that will be exposed [DataMember(IsRequired = true)] public Guid ID { get; set; } [DataMember(IsRequired = true)] public string FirstName { get; set; } [DataMember(IsRequired = true)] public string LastName { get; set; } [DataMember(IsRequired = true)] public string Sex { get; set; } [DataMember(IsRequired = true)] public Guid CompanyID { get; set; } } ```
Coordinator
Apr 10, 2013 at 5:51 AM
Yes, so if you try click that button for the GetAllEmployees() method you will see the XML and JSON equivalents for GetAllEmployeesRequest respectively, and since those have no properties, you get an empty XML root node or an empty JSON string, which are accurate serializations of the GetAllEmployeesRequest object.

Markus
Apr 10, 2013 at 4:08 PM
Edited Apr 10, 2013 at 4:09 PM
Markus,

Sorry, I didn't realize that the Codeplex editor had scrambled my code (it looked really nice before I hit send and was in an "insert code" block....

I am confused by your answer as I do have properties (remember, the invoke button works just fine). Or am I supposed to have properties that will expose the Employees list as JSON/XML?

Here is the code again, this time formatted better (I hope).

// Main contract

[ServiceContract]
public interface IEmployeesService
{
/// <summary> Retrieves a list of Employees</summary>
/// <param name=""request""> GetAllEmployeesRequest</param>
/// <returns>GetAllEmployeesResponse</returns>
[OperationContract]
GetAllEmployeesResponse GetAllEmployees(GetAllEmployeesRequest request);
// Other contracts omitted
}

// Request class

[DataContract]
public class GetAllEmployeesRequest
{
/// <summary>Constructor</summary>
/// <remarks>Explicitly set default values for all
/// properties in the constructor</remarks>
public GetAllEmployeesRequest()
{
}
}

// Response class (which is based on GenericResponse – also a datacontract – which
// has the success and failure properties and sets them to an empty value in the constructor

[DataContract]
public class GetAllEmployeesResponse : GenericResponse
{
///<summary>Constructor</summary>
/// <remarks>Explicitly set default values for all properties
/// in the constructor</remarks>
public GetAllEmployeesResponse() : base()
{
  Employees = new List<EmployeesQuickInformation>();
}

/// <summary>Actual list of Employees </summary>

[DataMember(IsRequired = true)]
public List<EmployeesQuickInformation> Employees { get; set; }
}

// the quickInformation class referenced by the response class

[DataContract]
public class EmployeesQuickInformation
{
/// <summary>Constructor</summary>
/// <remarks>Explicitly set default values for all properties
/// in the constructor</remarks>
public EmployeesQuickInformation()
{
  // Set all variables to their default value 
  ID = Guid.Empty; FirstName = string.Empty; LastName = string.Empty;
}
[DataMember(IsRequired = true)]
public Guid ID { get; set; }
[DataMember(IsRequired = true)]
public string FirstName { get; set; }
[DataMember(IsRequired = true)]
public string LastName { get; set; }
}
Coordinator
Apr 10, 2013 at 6:43 PM
When you click the button, you see the request object serialized to either XML or JSON. Your request object is this:
 [DataContract]
 public class GetAllEmployeesRequest
 {
     public GetAllEmployeesRequest()
     {
     }
 }
The JSON equivalent of that request object is this:
{}
The XML equivalent of that request object is this:
<GetAllEmployeesRequest />
Markus