I have the following output from a C# web service:
{"CallResult":[{"CompanyId":"AAA900134-904","CompanyName":"MID"}]}
I want the output to only contain an array of JSON like the following:
[{"CompanyId":"AAA900134-904","CompanyName":"MID"}]
I'm not sure how to customize the output. Do I have to return a string and customize the JSON manually or is there another way? Thanks.
Without more information, such as actual data example (this json refers to 1 object only), here is what I can suggest:
Create 2 custom classes as follows:
public class CallResultClass
{
public List<InnerClass> CallResult { get; set; }
}
public class InnerClass
{
public string CompanyId { get; set; }
public string CompanyName { get; set; }
}
Then, along with using System.Web.Script.Serialization;, you can deserialize the json as follows:
string json = "{\"CallResult\":[{\"CompanyId\":\"AAA900134-904\",\"CompanyName\":\"MID\"}]}";
JavaScriptSerializer js = new JavaScriptSerializer();
var callres = (CallResultClass)js.Deserialize(json, typeof(CallResultClass));
var companyInfo = callres.CallResult;
If your json contains a list of CallResults, a simple modification to the code can accommodate for that. There is no scenario where modifying the json string would be viable (there is always a clean way).
For reference & examples read JavaScriptSerializer Class.
I figured out a solution.
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "/CallResult/{username}/{company}")]
CallResult_Result[] CallResult(string username, string company);
I had to change
BodyStyle = WebMessageBodyStyle.Wrapped
to
BodyStyle = WebMessageBodyStyle.Bare
Related
I have a WCF to save some data to my db. In Dev Tools I can see the request payload as below:
{"OrderId":123456,"Year":"2017","CustomerId":999999,"LicencePlates":[{"licenceNumber":"222222222222222"}]}
My WCF service interface is as below:
[OperationContract]
[WebInvoke(UriTemplate = "/SaveLicenceData", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
void SaveLicenceData(int OrderId, int Year, string CustomerId, LicencePlate[] LicencePlates);
The licence plate class is:
public class LicencePlate
{
[DataMember]
public string LicenceNumber { get; set; }
}
With a breakpoint set, I can see the OrderId getting passed, the Year getting passed and the CustomerId getting passed. However LicenceNumber I keep getting null passed.
I tried making the overall class [Serializable] but the breakpoint isn't even getting hit when I add this. I also tried changing the annotation too [DataMember(Name = "licenceNumber")] but still getting null and then changed the annotation to [JsonProperty] and still getting null.
Is there something stupid I have missed here?
I think you have a case mismatch. In your payload you have
"licenceNumber":"222222222222222"
It should be
"LicenceNumber":"222222222222222"
When I try to retrieve a class filled with data I never retrieve the right data. The booleans in the class below always return false.
When I call the same GetState function from Postman of from Chrome without making any changes I do get the results I would expect
I have a class like wich looks something like this:
[DataContract]
public class State
{
[DataMember]
public bool Camera_1_Ok { get; set; }
[DataMember]
public bool Camera_2_Ok { get; set; }
[DataMember]
public bool Camera_3_Ok { get; set; }
}
My ServiceContract Interface looks like this:
[ServiceContract]
interface IConnectionService
{
[OperationContract]
[WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "GetState", RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml)]
State GetState();
}
The GetState implementation looks like this:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public sealed class WCFServer : IConnectionService
{
public State GetState()
{
State tempState = new State();
State.Camera_1_OK = true;
State.Camera_2_OK = true;
State.Camera_3_OK = true;
return tempState;
}
I made sure that both sides of the service have the same "State" class and the same "IConnectionService" Interface.
How come the booleans in the class that is returned to the calling machine are never set? And how come I do get the right data when I call the function from Chrome or Postman?
Awnsers to similar questions mentioned the [DataContract] and [DataMember] attributes but I already added these to my class.
PS: When I set the ResponseFormat to WebMessageFormat.Json on both sides of the service I get the data as expected. Sadly this will not be the solution since Xml format was requested.
BodyStyle = WebMessageBodyStyle.Bare
Then return a System.IO.Stream from your function.
After that, try to de-serialize your stream at receiver.
Trying to construct valid request to wcf restful service. But whole hour cannot do it, i dont get it why it's not work. Other APis what returns JSON works correctly, i tested them. Now need to fix request API.
I put break point to implementation of AddMeal method but she don't triggered. I think something wrong with my request or with Attributes
//Add Meal
[OperationContract]
[WebInvoke(UriTemplate = "AddMeal",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json, Method = "POST")]
bool AddMeal(string meal);
Your WCF method is expecting a string, however, the model binder will try to bind your JSON to a string which won't work. When using MVC you should use models instead, create a model that represents your JSON data e.g.
public class Meal
{
public DateTime EatedTime { get; set; }
public decimal Amount { get; set; }
public int PatientID { get; set; }
public int MealTypeID { get; set; }
...
}
Then update your signature to expect that model
bool AddMeal(Meal meal)
You should find the data is bound to the meal model.
I am creating a wcf self hosted service. I am using UriTemplate class to customize the urls to methods. the code snippet is given below
public interface ISelfService
{
[WebInvoke(Method = "POST", UriTemplate = "ack/{errorcode}/{uniquefileid}")]
[OperationContract]
void Ack(ErrorCode errorcode, string uniquefileid);
[WebInvoke(Method = "POST", UriTemplate = "filechanged/{metainfo}")]
[OperationContract]
void FileChanged(MetaInformation metainfo);
}
Whenever i run this program i am getting the following error
Operation 'FileChanged' in contract 'ISelfHostService' has a query
variable named 'metainfo' of type 'Natash.Common.MetaInformation',
but type 'Natash.Common.MetaInformation' is not convertible by
'QueryStringConverter'. Variables for UriTemplate query values must
have types that can be converted by 'QueryStringConverter'
Can any one tell me why is this happening?
And, I have not made any modification to the web.config file. Do i need to make any modification there?
MetaInformation is defined as follows
[DataContract]
public struct MetaInformation
{
[DataMember]
public string Author { get; set; }
[DataMember]
public string tags { get; set; }
[DataMember]
public string categories { get; set; }
[DataMember]
public string description { get; set; }
}
try this
public interface ISelfService{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/ack?errorcode={errorcode}&uniquefileid={uniquefileid}")]
void Ack(ErrorCode errorcode, string uniquefileid);
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/filechanged")]
void FileChanged(MetaInformation metainfo);}
From the message you posted it sounds like there are 2 definitions for the MetaInformation class (Gettrix.Common.MetaInformation & Natash.Common.MetaInformation).
It could be that both are in scope for WCF to see when instantiating the service. If so, it might think that the one that does not have a DataContract attribute (probably Natash.Common.MetaInformation) is what you are reffering to and therefore would not be usable for data transfer within the service.
Receiving the error "Object reference not set to an instance of an object" when posting JSON data to the below WCF Service.
My guess is the employee object isn't initialised but I'm unsure where that should be done as when I used a string a test it worked just fine.
Any suggestions are greatly appreciated.
Interface (IAccount.cs):
[ServiceContract(Namespace = "AccountService")]
public interface IAccountService
{
[OperationContract, WebInvoke(Method = "POST",
BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
string CreateAccount(Employee employee);
}
[DataContract]
public class Employee
{
[DataMember]
public string firstName { get; set; }
[DataMember]
public string lastName {get; set;}
}
Implementation (AccountService.svc)
AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class AccountService: IAccountService
{
public string CreateAccount(Employee employee)
{
string test = employee.firstName;
return test;
}
}
JSON Post Data:
{"firstName":"Test","lastName":"User"}
OK finally sorted this out, hopefully this helps someone with the same issue.
My initial JSON looked correct but doesn't work:{"firstName":"Test","lastName":"User"}. But by looking at the server trace you can see the inbuilt XML DeSerializer cannot map the elements to the object in the WCF Service method (employee object in my case) and this is the cause of the null reference error.
Putting the form attributes inside an object that matches the name of the service parameter however did the trick: {"employee":{"firstName":"test"}}
By default, WebGet's RequestFormat is set to XML. Set it to Json.