How can I view the request body in ASP.NET Web API from Visual Studio? - visual-studio

How can I view the request body in ASP.NET Web API from Visual Studio? In ASP.NET MVC, you can use QuickWatch to inspect the Request object and view the content of the body and any posted form data. From what I read, ASP.NET Web API doesn't allow you to read the body more than once.
This is very annoying to deal with when trying to figure out why a specific value wasn't bound correctly. Is there a quick way to do this without setting up tracing/logging?

The easiest it to install Fiddler. Then you will see everything that gets sent over the wire and inspect not only the request payload but the HTTP headers as well. And if you are consuming the API from javascript, things like FireBug, Chrome Developer Toolbar and IE Developer Tools will show you all network requests made by the website.
If you absolutely must inspect the traffic on the server then if you are hosting your Web API inside an ASP.NET application you could put the following line in your immediate window:
new StreamReader(HttpContext.Current.Request.InputStream).ReadToEnd()

if you need body >> Form-data
Post localhost:53356/api/carparksapi/GetRecod
key=jsonRequest and value=[{"abcd":"zxxx"}]
// API -Controller Method ::
var httpContext = (HttpContextWrapper)Request.Properties["MS_HttpContext"];
var foo = httpContext.Request.Form["jsonRequest"];
return foo; //This is value passed in request

For ASP.NET Core use this in the immediate window:
new System.IO.StreamReader(Request.Body).ReadToEnd()

For me #DarinDimitrov answer gave
error CS0246: The type or namespace name 'StreamReader' could not be found (are you missing a using directive or an assembly reference?)
Adding namespace did it
new System.IO.StreamReader(HttpContext.Current.Request.InputStream).ReadToEnd()
Hope this saves you some time

For me #Matas Vaitkevicius answer gave
error CS1061: 'HttpContextBase' does not contain a definition for
'Current' and no extension method 'Current' accepting a first argument
of type 'HttpContextBase' could be found (are you missing a using
directive or an assembly reference?)
Replacing HttpContext.Current with System.Web.HttpContext.Current did it for me
new System.IO.StreamReader(System.Web.HttpContext.Current.Request.InputStream).ReadToEnd()
Hope this saves you some time

Any of these answers could work if the position of the steam is at position 0.
HttpContext.Current.Request.InputStream.Position = 0;
var body = new StreamReader(HttpContext.Current.Request.InputStream).ReadToEnd();

Related

Blazor databinding to a javascript web component with complex object from C#

I've got a Blazor app that is referencing a custom web component (<omnibar-navigation>).
This component has an items property that should be a json object that looks something like this:
[{'title':'Home','icon':'places-home-1','url':'/','metadata':null,'items':null}, ...]
I'm wondering how to bind a C# complex object to that items property.
var options = new List<Nav> { new Nav { Title = "Home", Icon = "places-home-1", Url = "/" } };
Then the binding would be something like this (doesn't work):
<omnibar-navigation items="#options">...</omnibar-navigation>
A code repo for this problem is here: https://github.com/dahlsailrunner/blazor-oidc.
The page with the exact problem is here: https://github.com/dahlsailrunner/blazor-oidc/blob/master/Sample.Blazor/Pages/Stencil.razor
The component is imported on the Pages/_Host.cshtml file.
Great question. I noticed also some issues with binding a web component directly via Blazor data binding, especially with the connectedCallback of the web component which is a kwown issue.
But the great thing is:
If something in Blazor doesn't work, you can always use JavaScript Interop to make it work!
I've created here a blog post for you that shows how to integrate a web component via JS Interop that has such a property/attribute that takes a complex object: https://www.thomasclaudiushuber.com/2020/02/14/initializing-web-components-in-blazor-via-js-interop/
It also shows how to wrap the web component with a native Blazor component, so that you can bind it just with C#. :-)
Here is a git repo with all the code: https://github.com/thomasclaudiushuber/Blazor-Using-Custom-Web-Component
Happy coding,
Thomas
You're going to build a component with a Parameter property that receives an IEnumerable of your Nav type. You just need to deserialize your JSON and bind it to that collection.
Check this gist for how you can deserialize the JSON and bind to the collection in the index.razor file
https://gist.github.com/csharpfritz/c4dcfcc731826822e0764728bbd9d88c

ABP BoilerPlate: i cant see my exception message when i'm using UserFirendlyException

i'm using ABP ASP boilerplate .net core / angular client side frame work.
i want to show specific message when some condition exists in server side by raising UserFriendlyException("myMessage") but in client side only showing popup window
my end point API signature is like this async Task<BDto> CalcBodies(ADto input)
my problem solved by specifying LocalizationSourceName property of Service instance base on this post : GitHub link

Swagger does not show real error message

We are on .NET WebAPI framework and we are using swagger on top of web api for annotations and out of the box UI experience. So far, it just has been working great. However, when I return an error from WebAPI(Http 400) as following code:
return BadRequest("Some error");
However, when I do that, it seems like Swagger is not able to parse the error properly. It basically, show response 0. Which is wrong for sure because when I go to Chrome DevTools, I see that my request had a response of HTTP 400 as I expected.
How can I configure Swagger so that it is able to show the errors correctly? Or should I be throwing my errors a little bit differently to be able to see it in swagger?
You can annotate your actions like this
[ProducesResponseType(typeof(ResponseObjectTypeHere), 200)]
[ProducesResponseType(typeof(ErrorResponseObjectTypeHere), 400)]
You can also add something like this in the xml documentation if you enable swagger to read and use xml documentation
/// <response code="200">Description</response>
/// <response code="400">Description of error</response>
I used those in the .net core web api project with swagger, should be the same for regular .net web api project as well.
You can simply send the exception details to the client by enabling one of ABP's configurations (SendAllExceptionsToClients) in ***.Web.Core Module, like this:
public override void PreInitialize()
{
if (_env.EnvironmentName.ToLower() == "development")
Configuration.Modules.AbpWebCommon().SendAllExceptionsToClients = true;
}
Then you get the exception details on the client. Recommended only during development.

MVC WebAPI returning 500 error with no information

I've been having this problem for several days (now fixed and solution noted for anyone that comes across this issue and is pulling their hair out).
After my latest round of code changes to my Silverlight application which uses MVC4 WebAPI for data, I was having a problem with one of my HttpGet Actions which was returning IQueryable<oneofmyclasses>. Using Fiddler2 to watch the request, I could see I was getting an internal server error (500), with no body text to explain why. I received no errors thrown in my Action.
Check 1: I verified that my Action was indeed getting to the return collection.AsQueryable(); line with no errors. It was
Check 2: I verified that my data was serializing to JSON with no errors using this code (g is my collection):
var json = new JsonMediaTypeFormatter();
json.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
ObjectContent<IEnumerable<Model.MenuGroup>> responseContent = new ObjectContent<IEnumerable<Model.MenuGroup>>(g, json);
MemoryStream ms = new MemoryStream();
responseContent.CopyToAsync(ms).Wait();
ms.Position = 0;
var sr = new StreamReader(ms);
var str = sr.ReadToEnd();
This also worked. I also tested it using XML formatter even though I was pretty sure it only ever used JSON (can't be too careful).
Check 3: Enabled .Net Framework debugging. This time when the error occured (in HttpApplication.cs) VS 2012 caught it.
My error:
Despite having marked the property with these attributes,
[XmlIgnore]
[IgnoreDataMember]
[JsonIgnore]
the .Net Source was calling a get on one of my properties. The catch, it was a write-only property. I simply added
get { return null; }
and the problem was solved.
I probably should have just done Check 3 first, but my previous experience with this error has shown it to usually be an error trying to serialize my objects, which was why I had a bit of a head scratcher when they did serialize properly and the error persisted.
How I solved it:
Enabled .Net Framework debugging. Tools -> Options -> Debugging -> Check 'Enable .NET Framework source stepping'
This time when the error occured (in HttpApplication.cs) VS 2012 caught it.

Debugging: IE6 + SSL + AJAX + post form = 404 error

The Setting:
The program in question tries to post form data via an AJAX call to a target procedure contained in the same package as the caller. This is done for a site that uses a secure connection (HTTPS). The technology used here is PLSQL and the DOJO JavaScript library. The development tool is basically a text editor.
Code Snippet:
> function testPost() {
>> dojo.xhrPost( {
url: ''dr_tm_w_0120.test_post'',
form: ''orgForm'',
load: testPostXHRCallback,
error: testPostXHRError
});
}
> function testPostXHRCallback(data,ioArgs) {
>> alert(''post callback'');
try{
dojo.byId("messageDiv").innerHTML = data;
}
catch(ex){
if(ex.name == "TypeError")
{
alert("A type error occurred.");
}
}
return data;
}
>
function testPostXHRError(data, ioArgs) {
>> alert(data);
alert(''Error when retrieving data from the server!'');
return data;
}
The Problem:
When using IE6 (which the entire user-base uses), the response sent back from the server is a 404 error.
Observations:
The program works fine in Firefox.
The calling procedure cannot target any procedures within the same package.
The calling procedure can target outside sites (both http, https).
The other AJAX calls in the package that are not posts of form data work fine.
I've searched the internets and consulted with senior-skilled team members and haven't discovered anything that satisfactorily addresses the issue.
*Tried Q&A over at Dojo support forums.
The Questions:
What troubleshooting techniques do you recommend?
What troubleshooting tools do you recommend for HTTPS analyzing?
Any hypotheses on what the issue might be?
Any ideas for workarounds that aren't total (bad) hacks?
Ed. The Solution
lomaxx, thx for the fiddler tip. you have no idea how awesome it was to get that and use it as a debugging tool. after starting it up this is what i found and how i fixed it (at least in the short term):
> ef Fri, 8 Aug 2008 14:01:26 GMT dr_tm_w_0120.test_post: SIGNATURE (parameter names) MISMATCH VARIABLES IN FORM NOT IN PROCEDURE: SO1_DISPLAYED_,PO1_DISPLAYED_,RWA2_DISPLAYED_,DD1_DISPLAYED_ NON-DEFAULT VARIABLES IN PROCEDURE NOT IN FORM: 0
After seeing that message from the server, I kicked around Fiddler a bit more to see what else I could learn from it. Found that there's a WebForms tab that shows the values in the web form. Wouldn't you know it, the "xxx_DISPLAYED_" fields above were in it.
I don't really understand yet why these fields exist, because I didn't create them explicitly in the web PLSQL code. But I do understand now that the target procedure has to include them as parameters to work correctly. Again, this is only in the case of IE6 for me, as Firefox worked fine.
Well, that the short term answer and hack to fix it. Hopefully, a little more work in this area will lead to a better understanding of the fundamentals going on here.
First port of call would be to fire up Fiddler and analyze the data going to and from the browser.
Take a look at the headers, the url actually being called and the params (if any) being passed to the AJAX method and see if it all looks good before getting to the server.
If that all looks ok, is there any way you can verify it's actually hitting the server via logging, or tracing in the AJAX method?
ed: another thing I would try is rig up a test page to call the AJAX method on the server using a non-ajax based call and analyze the traffic in fiddler and compare the two.

Resources