WCF String DataMemeber fails with special characters - wcf

I have a simple DataContract structured in this way:
[DataMember(EmitDefaultValue = false, IsRequired = true, Name = "TablePath", Order = 1)]
public string TablePath { get; set; }
The Value that I try to insert is something like that:
%PATH%\%SPECIAL%\file.txt
And I receive this message using the WCF Test Client UI
"... is not a valid value for this type."
I tried different combinations of characters, and for example something like this works great "%PATH%".
The problem is if there is a combination like "%\".
How I can fix this problem as I will receive any type of characters inside this property?
Thank you in advance.

Did you try adding the # sign before the string #"%PATH%\%SPECIAL%\file.txt" ?
Without it I think you need to use "\ \" instead of "\" .....

It seems that the problem is only with the WCF Test Client tool. If I use the same metadata through C# it works ... Weird as I don't have a UI now to test my services ... I must work with TDD.

Related

Exclude controller from route with string param .NET core

I want to have an endpoint that looks like: localhost:5000/abc123
This is basically to replicate the functionality of tinyurl.
Controller
[HttpGet("/{myString}")]
public async Task<IActionResult> Get(string myString)
{}
This works but all files now come through this contoller eg: localhost:5000/runtime.js etc
Is this possible to do only for certain strings?
Use Route constraint to filter values for myString
For example, if a file name is a string containing a dot . is a valid suggestion in your case, you can use the following regex to accept alphanumeric strings
[HttpGet("/{myString::regex(^\\w+$)}")]

JsonConvert.DeserializeObject - Handling Empty Strings

I am using Json.NET to serialize an object to be sent to a compact framework 3.5 device (lucky me).
My class on the compact device is:
public class Specification
{
public Guid Id { get; set; }
public String Name { get; set; }
public String Instructions { get; set; }
}
The Json being returned sent to the device is (notice the null for instructions):
string json = #"{""Name"":""Test"",""Instructions"":null,""Id"":""093a886b-8ed4-48f0-abac-013f917cfd6a""}";
...and the method being used to deserialize the json is...
var result = JsonConvert.DeserializeObject<Specification>(json);
On the server I'm using the following to create the Json:
var serializer = new JsonSerializer();
serializer.Formatting = Formatting.None;
serializer.Serialize(context.HttpContext.Response.Output, this.Data);
The problem is that on the compact framework, it's failing to put a value into result.Instructions which is causing a null reference when it is referenced later in the code.
I'm using Newtonsoft.Json.Compact v3.5.0.0 (I think that's the latest version), and on the server I'm using Newtonsoft.Json 4.5.0.0.
Question
How can I either:
a) Change the server code to stick a "" instead of a null value in where a string is null.
or
b) Change the compact framework code to be able to handle null value strings.
Things I've tried
I've been looking through the documentation/examples of Json.Net and have tried a multitude of things like a implementing a DefaultContractResolver, and a custom JsonContract. Maybe the answer lies within those but my lack of understanding of Json.Net at this level isn't helping!!
Further info
I was using System.Runtime.Serialization.Json.DataContractJsonSerializer for the server side serialisation, which did generated quotes in the event of empty strings. Unfortunately, I need more flexibility with the serialization which is why I've started using Json.Net.
Any hints/tips appreciated.
OK - no answers, but having search all yesterday afternoon I went to bed, and search again this morning to find: Serializing null in JSON.NET, which pretty much answers my question.

Getting the message from jquery validation when using UnobtrusiveJavaScript

Hey there StackOverflow enthusiasts.
I am attempting to update an old site of mine to the newest edition of Asp.net MVC4. It was previously on MVC2, and on MVC2 it allowed me to pretty much separate my jquery and client side stuff from any of the backend stuff. But I guess with MVC4 they want you to have a lot of your validation stuff tied directly to your models and so on.
But I have a client side jquery validation script that was working pretty well before, and I was wondering, how can I get it to work again. Specifically, I had a field that would not be validated if the user entered in more than 4000 characters. Otherwise it would not be required. Here is the client side code that worked before in MVC2....
Comment: {
required: function (element) {
return $(element).val().length > 4000;
},
maxlength: 4000
}
and the message that would be displayed if validation was not passed...
messages: {
...
Comment: 'Why dont you stop attempting to put in more than 4000 characters? Thanks...'
}
How can I do that with MVC four? To get anything to display in another field I noticed I needed to put a required over the field in my model...
[Required(ErrorMessage = "Please select an Admit Date")]
public DateTime? AdmitDate { get; set; }
Is there a way to write a requirement function so that it is only required under certain circumstances? I would prefer to keep it client side to keep my concerns separate if you know what I mean. Any help would be appreciated.
You can use [Required] and [StringLength] to constrain the input on your Comment.
[Required(ErrorMessage = "Please fill in a comment")]
[StringLength(4000, ErrorMessage = "Why dont you stop attempting to put in more than 4000 characters? Thanks...")]
public string Comment { get; set; }
Conditional required constraints are not covered by default data annotations. The default way of handling 'complex' validations is by implementing the IValidatableObject interface on your model.
However, since you are looking for a client-side solution, we can look at other frameworks that may solve this problem for you. For instance, MVC Foolproof Validation supports a [RequiredIf] attribute that also works client-side.

SQL "in" type behaviour with a WCF Dataservice

Here's what I want to do :
string[] names= {"Dave","Mike","Sara","Roger"};
var events = eventsDB.where(a=>names.Contains(a.name));
I think that's pretty clear. Where eventsDB is a Linq to SQL connection, all is well - But this won't work with a service. Is there any way to achieve this?
Cheers!
Thanks for the tips guys, I think I've found a way to get what I want from the web service without having to add another method to the service by simply building the query URI manually ... partly.
string[] names = { "Dave", "Mike", "Sara", "Roger" };
StringBuilder sb = new StringBuilder();
sb.Append("(");
foreach (string s in names)
{
sb.Append(String.Format("name eq '{0}'",s));
sb.Append(" or ");
}
sb.Remove(sb.Length - 4, 4);
sb.Append(")");
var events = eventsDB.AddQueryOption("$filter",sb.toString());
notice the AddQueryOption function
You could expose a service method which returns an array.
Then you could call it like
serviceProxy.serviceMethod.where(....
But I don't think you would want to so this. For a start, a database and a service are completely different things.
Linq to WCF? Nice idea but does not compute.
OData the underlying protocol for WCF Data Services currently doesn't support this.
You could implement a service operation to do this on the server side and pass in the list of values as a parameter. Note that for service operation the list would have to be concatenated to a single string, so for example comma separated list. If you would go with action instead you can pass in the list directly.
The other option is to construct a query similar to that. If the number of values in the array is small you can construct a query like
Where(a => a.Name == "John" || a.Name == "Mary" || ...)

Optional query string parameters in URITemplate in WCF?

I'm developing some RESTful services in WCF 4.0. I've got a method as below:
[OperationContract]
[WebGet(UriTemplate = "Test?format=XML&records={records}", ResponseFormat=WebMessageFormat.Xml)]
public string TestXml(string records)
{
return "Hello XML";
}
So if i navigate my browser to http://localhost:8000/Service/Test?format=XML&records=10, then everything works as exepcted.
HOWEVER, i want to be able to navigate to http://localhost:8000/Service/Test?format=XML and leave off the "&records=10" portion of the URL. But now, I get a service error since the URI doesn't match the expected URI template.
So how do I implement defaults for some of my query string parameters? I want to default the "records" to 10 for instance if that part is left off the query string.
Note: This question is out of date, please see the other answers.
This does not appear to be supported.
However, Microsoft has been made aware of this issue and there is a work-around:
You can get the desired effect by
omitting the Query string from the
UriTemplate on your WebGet or
WebInvoke attribute, and using
WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters
from within your handlers to inspect,
set defaults, etc. on the query
parameters.
https://connect.microsoft.com/VisualStudio/feedback/details/451296/
According to this answer this is fixed in .NET 4.0. Failing to supply the query string parameter seems to result in its being given the default value for the type.
Check this blog post out. Makes sense to me, and comes with a class to parse out the query string parameters.
http://blogs.msdn.com/b/rjacobs/archive/2009/02/10/ambiguous-uritemplates-query-parameters-and-integration-testing.aspx
Basically don't define the query string parameters in the UriTemplate so it matches with/without the parameters, and use the sample class to retrieve them if they're there in the method implementation.
This seems to work in WCF 4.0.
Just make sure to set your default value in your "Service1.svc.cs"
public string TestXml(string records)
{
if (records == null)
records = "10";
//... rest of the code
}
While this is an old question, we still come to this scenario from time to time in recent projects.
To send optional query parameters, I created WCF Web Extensions nuget package.
After installation, you can use the package like this:
using (var factory = new WebChannelFactory<IQueryParametersTestService>(new WebHttpBinding()))
{
factory.Endpoint.Address = new EndpointAddress(ServiceUri);
factory.Endpoint.EndpointBehaviors.Add(new QueryParametersServiceBehavior());
using (var client = factory.CreateWebChannel())
{
client.AddQueryParameter("format", "xml");
client.AddQueryParameter("version", "2");
var result = client.Channel.GetReport();
}
}
Server side you can retrieve the parameters using WebOperationContext:
WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters;