Fiddler - Change HTTP Request Header - wcf

I wish to create a HTTP request header using Fiddler.
I have a Service running which exposes a Method, which has an object parameter. The object looks like this:
[DataMember]
public string Name { get; set; }
[DataMember]
public string Data { get; set; }
[DataMember]
public string Details { get; set; }
....
Does anyone know how I can populate these objects and send them to my WCFServices? I am using localhost.

Solved by:
Opening Fiddler, clicking on Composer, adding:
Content-Type: application/json; charset=utf-8 In the Parsed tab.
And Key pair values in the Request Body, e.g:
{
"Name" : "Arnold",
"Data" : "SomeDataHere"
}

how I can populate these objects
Take a look at SOAP UI or at the WCF Test Client.

Related

How to work with [Required] attribute & Model State Validation within Web Api Put

Currently I am facing, a problem, when try to call Web Api put method from MVC Api Client, lets describe my code structure bellow
Test Model (Web Api end)
public sealed class Test
{
[Required]
public int Id { get; set; }
[Required]
public string Name { get; set; }
}
Web Api PUT Method
public HttpResponseMessage Put(string token, IEnumerable<Test> data)
{
[...]
return Request.CreateResponse(HttpStatusCode.OK);
}
Web Api Custom Filter
public sealed class ValidateFilterAttribute : ActionFilterAttribute
{
/// <summary>
///
/// </summary>
/// <param name="actionContext"></param>
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (!actionContext.ModelState.IsValid)
{
actionContext.Response = actionContext.Request.CreateErrorResponse(
HttpStatusCode.BadRequest, actionContext.ModelState);
}
}
}
Call from Web Api Client
async System.Threading.Tasks.Task VerifiedFAccount()
{
using (var client = GetHttpClient())
{
var url = string.Concat("/api/Verfication", "?token=", token);
var data = new SampleTest { Id = 1, Name = "xxx" };
var temp = new List<SampleTest>();
temp.Add(data);
using (HttpResponseMessage response = await client.PutAsJsonAsync
<IEnumerable<SampleTest>>(url, temp).ConfigureAwait(false))
{
if (response.IsSuccessStatusCode)
{
}
}
}
Client code unable to execute Api call (Even I placed the debug point within Web Api Put method, unable to hit the debug point) & always got the bellow error response
{StatusCode: 500, ReasonPhrase: 'Internal Server Error', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
Pragma: no-cache
X-SourceFiles: =?UTF-8?B?STpcRGV2QXJlYUxvY2FsXENPTVBBTlkgLSBQU1AgUFJPSkVDVFNcRS1BdXRob3JpdHkgLSBBdXN0cmVsaXlhXFNvdXJjZUNvbnRyb2xcVHJ1bmtcMDYgRGVjIDIwMTNcRS1BdXRob3JpdHkuQXBpIC0gMjAxM1xFYXV0aG9yaXR5LldlYi5BcGkuUHJlc2VudGF0aW9uTGF5ZXJcYXBpXFNtc2ZBY2NvdW50VmVyZmljYXRpb24=?=
Cache-Control: no-cache
Date: Mon, 14 Apr 2014 11:23:27 GMT
Server: Microsoft-IIS/8.0
Content-Length: 2179
Content-Type: application/json; charset=utf-8
Expires: -1
}}
But when I remove [Required] from Test Model (Web Api end). Then above described client code execute successfully.
Please tell me what is the reason of this kind of confusing behavior ?
The issue you are facing might be because of the behaviour of the default configuration when it comes to data validation. You have a Required attributed on a non-nullable type and since int can't be null, it will always have a value (the default of 0) if the incoming request does not provide the value.
In these cases, the model validator will throw an exception because it doesn't make sense to have a Required attribute on a property that can't be null.
The straightforward way you would be to change a setting on your MVC application:
DataAnnotationsModelValidatorProvider
.AddImplicitRequiredAttributeForValueTypes = false;
This will get rid of the error that is thrown by the framework. This introduce the problem that you will get a value of 0 even when the request does not include the property. It makes more sense to have your integer be of Nullable<int>. The Required attribute will be able to handle a null value and you will know whether or not the incoming request included the property
public sealed class Test
{
[Required]
public int? Id { get; set; }
[Required]
public string Name { get; set; }
}

POST controller value is always NULL

Firstly thank you for taking the time out to read this post.
I've been building my first asp.net 4.5 MVC4 Web Api, but the value received in the controll POST method is always NULL.
To test the POST api method I've tried Fiddler and Google Chrome Simple REST Clinet but the result is always the same.
Here's my code:
Controller (POST)
// POST api/Terminal
public HttpResponseMessage PostTerminal(Terminal terminal)
{
if (terminal == null)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, terminal);
}
if (ModelState.IsValid)
{
db.Terminals.Add(terminal);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, terminal);
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = terminal.Id }));
return response;
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
}
Model Class
public class Terminal
{
public int Id { get; set; }
[Required]
public int TerminalId { get; set; }
[Required]
public string Tag { get; set; }
[Required]
public DateTime TagDate { get; set; }
}
In the above code, the value received in the POST method terminal is always NULL.
Here's the command I've been using to POST using Fiddler:
Method:
POST
Address:
http://localhost:52036/api/terminal
Header:
Content-Type: application/json
Host: localhost:52036
Content-Length: 60
Body:
{"TerminalId":123,"Tag":"222","TagDate":2014-04-13 04:22:12}
----------- EDIT - 13-04-2014 14:56 -------------
I have modified my Fiddler http post request as advised to in some of the replies to this question with the following details. However I keep getting a 500 HTTP error and my API code doesn't even reach the Controller when testing in VS2013 debug mode.
Address
POST
http://localhost:52036/api/terminal/
Header
Content-Type: application/json; charset=utf-8
Host: localhost:52036
Content-Length: 62
Body
{"TerminalId":123,"Tag":"222","TagDate":"2014-04-13 04:22:12"}
-------------- Edit 13/04/2014 20:38 -----------------
Ok, using Google's Chrome REST Client, I've noticed the following return error message:
{"Message":"An error has occurred.","ExceptionMessage":"Property
'TerminalId' on type 'ClockingDemo.Models.Terminal' is invalid.
Value-typed properties marked as [Required] must also be marked with
[DataMember(IsRequired=true)] to be recognized as required. Consider
attributing the declaring type with [DataContract] and the property
with
[DataMember(IsRequired=true)].","ExceptionType":"System.InvalidOperationException","StackTrace":"
at
System.Web.Http.Validation.Validators.ErrorModelValidator.Validate(ModelMetadata
metadata, Object container)\r\n at
System.Web.Http.Validation.DefaultBodyModelValidator.ShallowValidate(ModelMetadata
metadata, ValidationContext validationContext, Object container)\r\n
at
System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata
metadata, ValidationContext validationContext, Object container)\r\n
at
System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata
metadata, ValidationContext validationContext)\r\n at
System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata
metadata, ValidationContext validationContext, Object container)\r\n
at
System.Web.Http.Validation.DefaultBodyModelValidator.Validate(Object
model, Type type, ModelMetadataProvider metadataProvider,
HttpActionContext actionContext, String keyPrefix)\r\n at
System.Web.Http.ModelBinding.FormatterParameterBinding.<>c__DisplayClass1.b__0(Object
model)\r\n at
System.Threading.Tasks.TaskHelpersExtensions.<>c__DisplayClass361.<>c__DisplayClass38.<Then>b__35()\r\n
at
System.Threading.Tasks.TaskHelpersExtensions.<>c__DisplayClass49.<ToAsyncVoidTask>b__48()\r\n
at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func1
func, CancellationToken cancellationToken)"}
I think the problem is coming from the fact that my INTEGER property TerminalId is defined as [Required]. I have a feeling there might be an issue with setting a non-NULLABLE property and [Required].
Very much open to suggestions.
----------------- ANSWER ---------------
I finally stumbled across this thread which solved the problem for me.
DataAnnotation for Required property
Simply paste this into the Global.asax file:
GlobalConfiguration.Configuration.Services.RemoveAll(
typeof(System.Web.Http.Validation.ModelValidatorProvider),
v => v is InvalidModelValidatorProvider);
I'm still open to other solutions if you believe there is a better method.
In Fiddler you have to use like below
Your Request Body should like this {"TerminalId":123,"Tag":"222","TagDate":"2014-04-13 04:22:12"}
and in your request header you need to pass content type like this Content-Type: application/json; charset=utf-8
In my case I have a hybrid ASP.NET Web Forms with MVC and Web API.
Just solved like this:
public HttpResponseMessage PostTerminal(JObject jsonMessage)
{
var terminal = jsonMessage.ToObject<Terminal>();
if (terminal == null)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, terminal);
}
...
}
References: http://weblog.west-wind.com/posts/2012/May/08/Passing-multiple-POST-parameters-to-Web-API-Controller-Methods

Return a model containing stream in ASP MVC4 Webapi

My model class looks like this
public Stream FileStream { get; set; }
public string FileName { get; set; }
public string ContentType { get; set; }
Is it possible to return this model to webapi?
A Stream is just a pointer to some actual resource. If you want to send this to the response and be able to serialize it you could use a byte array.
Or event better, write the Stream to the response and then use standard HTTP headers for the 2 other properties:
Content-Type: application/pdf
Content-Disposition: attachment; filename=report.pdf
... the actual content comes here
You could also consider writing a custom MediaTypeFormatter to achieve this as shown in this article.
No. This cannot be automatically serialised. But returning a stream is easy. See here.

ServiceStack not binding FormData on multi-part request

I'm performing file uploads from Javascript. The file is transferred fine, but the additional form data passed in the request is not bound to the request DTO.
From Chrome inspector:
------WebKitFormBoundaryunl7tsdqzGBvtsUH
Content-Disposition: form-data; name="albumId"
1037
------WebKitFormBoundaryunl7tsdqzGBvtsUH
Content-Disposition: form-data; name="file"; filename="Tulips.jpg"
Content-Type: image/jpeg
RequestDTO
public class UploadRequest : IRequiresRequestStream
{
public Stream RequestStream { get; set; }
public string FileName { get; set; }
public long? AlbumId { get; set; }
}
The image is properly bound, but other items from form-data. What's interesting is that
Request.FormData contains the entry for albumId.
Any clues ?
I think this is due to the fact that UploadRequest is inheriting from
IRequiresRequestStream thus bypassing any binding of form data to the DTO.

ASP.Net Web Api not binding model on POST

I'm trying to POST JSON data to a Web Api method but the JSON data is not binding to the model.
Here's my model:
[DataContract]
public class RegisterDataModel
{
[DataMember(IsRequired = true)]
public String SiteKey { get; set; }
[DataMember(IsRequired = true)]
public String UserId { get; set; }
[DataMember(IsRequired = true)]
public String UserName { get; set; }
}
Here's my Web Api action:
public class RegisterController : ApiController
{
public Guid Post([ModelBinder] RegisterDataModel registerDataModel)
{
if (!ModelState.IsValid)
{
throw new ModelStateApiException(ModelState);
}
var userProfileDataContract = userProfileBusinessLibrary.GetNewOne();
userProfileDataContract.UserId = registerDataModel.UserId;
userProfileDataContract.UserName = registerDataModel.UserName;
var userKey = userProfileBusinessLibrary.Register(registerDataModel.SiteKey, userProfileDataContract);
return userKey;
}
}
Before I added [ModelBinder], registerDataModel was null. After adding [ModelBinder], registerDataModel is a RegisterDataModel instance, but all of the property values are null.
Here's my Request via Fiddler:
http://local.testwebsite.com/api/register
Request Headers:
User-Agent: Fiddler
Host: local.testwebsite.com
Content-Length: 89
Content-Type: application/json; charset=utf-8:
Request Body:
{
"SiteKey":"qwerty",
"UserId": "12345qwerty",
"UserName":"john q"
}
What am I missing to make my post data bind to the RegisterDataModel properties? Thanks for your help.
Not related to the OP's problem, but the title of the question
led me here when I used (public) fields instead of properties
in the Model class (i.e. no {get; set;}).
It turned out that this also causes the binding to fail.
Maybe helps someone.
How are you creating the JSON request? Through Fiddler request builder? Try just the following in the request body.
{
"SiteKey":"qwerty",
"UserId": "12345qwerty",
"UserName":"john q"
}
I'm guessing 'Request Body:' is also part of your request body. Remove that and check.
In my case, app's requests are passed through a middleware called "API Manager" for authentication / authorization before forwarding to my .NET Web API. POST parameter isn't binded because, for some reason I'm no idea why, the "Content-Length" is emitted from the Headers.The reason is because, the default JsonMediaTypeFormatter always check requests' Content-Length before doing model binding, and if the Content-Length is not presented it will set the parameter to NULL.