Why use HttpClient for Synchronous Connection

[Origin]: https://stackoverflow.com/questions/14435520/why-use-httpclient-for-synchronous-connection

I am building a class library to interact with an API. I need to call the API and process the XML response. I can see the benefits of using HttpClient for Asynchronous connectivity, but what I am doing is purely synchronous, so cannot see any significant benefit over HttWebRequests.

If anyone can shed any light I would greatly appreciate it. I am not one for using new technology for the sake of it.

You could use HttpClient for synchronous requests just fine:

using (var client = new HttpClient())
{
    var response = client.GetAsync("http://google.com").Result;

    if (response.IsSuccessStatusCode)
    {
        var responseContent = response.Content; 

        // by calling .Result you are synchronously reading the result
        string responseString = responseContent.ReadAsStringAsync().Result;

        Console.WriteLine(responseString);
    }
}

As far as why you should use HttpClient over WebRequest is concerned, well, HttpClient is the new kid on the block and could contain improvements over the old client.

Advertisements

Pass NTLM with Postman

[Origin]: https://stackoverflow.com/questions/37341304/pass-ntlm-with-postman

Is there a way to pass Windows Authentication with postman?

I have added this in header but still 401 Unauthorized.

Authorization: NTLM TkFcYWRtaW46dGVzdA==

As suggested by this link. I’ve encrypted as Unicode (UTF-16, little-endian) but of no use.

Any Ideas?

I got this working by running Fiddler first.

  1. Run Fiddler (I’m using 4.6.2.3)
  2. Fiddler Menu: Rule -> Automatically Authenticate = true
  3. Postman: Check that Authorization type = No Auth
  4. Browse api.

you can use the the NTLM authorization exist in the Authorization tab same as this photo

enter image description here

Single controller with multiple GET methods in ASP.NET Web API

[Origin]: https://stackoverflow.com/questions/9499794/single-controller-with-multiple-get-methods-in-asp-net-web-api

In Web API I had a class of similar structure:

public class SomeController : ApiController
{
    [WebGet(UriTemplate = "{itemSource}/Items")]
    public SomeValue GetItems(CustomParam parameter) { ... }

    [WebGet(UriTemplate = "{itemSource}/Items/{parent}")]
    public SomeValue GetChildItems(CustomParam parameter, SomeObject parent) { ... }
}

Since we could map individual methods, it was very simple to get the right request at the right place. For similar class which had only a single GET method but also had an Object parameter, I successfully used IActionValueBinder. However, in the case described above I get the following error:

Multiple actions were found that match the request: 

SomeValue GetItems(CustomParam parameter) on type SomeType

SomeValue GetChildItems(CustomParam parameter, SomeObject parent) on type SomeType

I am trying to approach this problem by overriding the ExecuteAsync method of ApiController but with no luck so far. Any advice on this issue?

Edit: I forgot to mention that now I am trying to move this code on ASP.NET Web API which has a different approach to routing. The question is, how do I make the code work on ASP.NET Web API?

shareedit

This is the best way I have found to support extra GET methods and support the normal REST methods as well. Add the following routes to your WebApiConfig:

routes.MapHttpRoute("DefaultApiWithId", "Api/{controller}/{id}", new { id = RouteParameter.Optional }, new { id = @"\d+" });
routes.MapHttpRoute("DefaultApiWithAction", "Api/{controller}/{action}");
routes.MapHttpRoute("DefaultApiGet", "Api/{controller}", new { action = "Get" }, new { httpMethod = new HttpMethodConstraint(HttpMethod.Get) });
routes.MapHttpRoute("DefaultApiPost", "Api/{controller}", new {action = "Post"}, new {httpMethod = new HttpMethodConstraint(HttpMethod.Post)});

I verified this solution with the test class below. I was able to successfully hit each method in my controller below:

public class TestController : ApiController
{
    public string Get()
    {
        return string.Empty;
    }

    public string Get(int id)
    {
        return string.Empty;
    }

    public string GetAll()
    {
        return string.Empty;
    }

    public void Post([FromBody]string value)
    {
    }

    public void Put(int id, [FromBody]string value)
    {
    }

    public void Delete(int id)
    {
    }
}

I verified that it supports the following requests:

GET /Test
GET /Test/1
GET /Test/GetAll
POST /Test
PUT /Test/1
DELETE /Test/1

Note That if your extra GET actions do not begin with ‘Get’ you may want to add an HttpGet attribute to the method.

shareedit

The ‘Access-Control-Allow-Origin’ header contains multiple values

[Origin]: https://stackoverflow.com/questions/37594403/the-access-control-allow-origin-header-contains-multiple-values

i’m trying to send get request to api like it’s a login url

var url = "http://demo.software.travel/gptp/api/authorization?apiKey=****&alias=****&login=****&password=****"
$.get(url, function(data) {
    console.log(data);
});

i’m getting this in my console this error

XMLHttpRequest cannot load http://demo.software.travel/gptp/api/authorization?apiKey=****&alias=****&login=****&password=****. 
The 'Access-Control-Allow-Origin' header contains multiple values 'http://travellights.net, *', but only one is allowed. 
Origin 'http://travellights.net' is therefore not allowed access.

i’m trying to see questions here to solve it but i didn’t get what i need to change, this is annoying actually.

The ‘Access-Control-Allow-Origin’ header contains multiple values

this solved by asp.net web.congif

By the way i’m using CHROME BROWSER any help i appreciate.

UPDATE response headers:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:origin, x-requested-with, Content-Type, accept, Token
Access-Control-Allow-Methods:GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS
Access-Control-Allow-Origin:http://travellights.net
Access-Control-Allow-Origin:*
Connection:close
Content-Encoding:gzip
Content-Type:application/json;charset=utf-8
Date:Thu, 02 Jun 2016 16:41:18 GMT
Server:nginx/1.1.19
Set-Cookie:JSESSIONID=51FEE1A1206B9B481DD3EEA4167A9256; Path=/gptp
Vary:Origin
Vary:Accept-Encoding
X-UA-Compatible:IE=EmulateIE7

Request Headers:

Accept:application/json, text/javascript, */*; q=0.01
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8,ar;q=0.6,en-GB;q=0.4
Connection:keep-alive
Host:demo.software.travel
Origin:http://travellights.net
Referer:http://travellights.net/b2b/Pages/login?
User-Agent:Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
shareedit

You are attempting to do Cross-origin resource sharing (CORS) which is a mechanism that allows restricted resources on a web page to be requested from another domain outside the domain from which the resource originated. (such as accessing fonts or JSON files).

Browsers restrict your access to resources from other origins as of Same-origin policy as a security measure for internet users.

To get around this issue you have to options:

  1. allow CORS on the domain http://demo.software.travel (but there is are security concerns, more description about it here: https://www.owasp.org/index.php/HTML5_Security_Cheat_Sheet#Cross_Origin_Resource_Sharing)

Enable CORS on the server to be able to access other domains through. this can be done by adding the following headers to responses:

Access-Control-Allow-Origin: http://travellights.net Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
  1. if you are not granted resource sharing with that domain, you are allowed to use JSONP for read only operations (JSONP is inherently read-only)

JSONP wraps a JSON object in a callback, which technically makes the request a non-restricted resource (a script tag) hence can be shared across domains.

it can be done via vanilla js by adding a script tag onto the page.

function process(data) {
    // do stuff with JSON
}

var script = document.createElement('script');
script.src = '//domainURL?callback=process'

document.getElementsByTagName('head')[0].appendChild(script);

or you can use jquery to achieve the same:

$.ajax({enter code here
    url: "http://query.yahooapis.com/v1/public/yql",
    jsonp: "callback",
    dataType: "jsonp",
    data: {
        q: "select title,abstract,url from search.news where query=\"cat\"",
        format: "json"
    },
    success: function( response ) {
        console.log( response ); // server response
    }
});

jquery documentation: https://learn.jquery.com/ajax/working-with-jsonp/

shareedit

If you set “Full” CORS (with OPTION pre-request) on in nginx by add ‘access-control-allow-origin *’ and independently you add that header (for Simple CORS – without OPTION pre-request) to each response in SERVER (eg. php):

header('Access-Control-Allow-Origin', "*");

Then you will get this problem. Solution: remove code which add this header in server if already you add this header in your nginx config 🙂

I found this advice here

shareedit

Why does my JavaScript get a “No ‘Access-Control-Allow-Origin’ header is present on the requested resource” error when Postman does not?

[Origin]: https://stackoverflow.com/questions/20035101/why-does-my-javascript-get-a-no-access-control-allow-origin-header-is-present

I am trying to do authorization using JavaScript by connecting to the RESTful API built in Flask. However, when I make the request, I get the following error:

XMLHttpRequest cannot load http://myApiUrl/login. No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘null’ is therefore not allowed access.

I know that the API or remote resource must set the header, but why did it work when I made the request via the Chrome extension Postman?

This is the request code:

$.ajax({
    type: "POST",
    dataType: 'text',
    url: api,
    username: 'user',
    password: 'pass',
    crossDomain : true,
    xhrFields: {
        withCredentials: true
    }
})
    .done(function( data ) {
        console.log("done");
    })
    .fail( function(xhr, textStatus, errorThrown) {
        alert(xhr.responseText);
        alert(textStatus);
    });

If I understood it right you are doing an XMLHttpRequest to a different domain than your page is on. So the browser is blocking it as it usually allows a request in the same origin for security reasons. You need to do something different when you want to do a cross-domain request. A tutorial about how to achieve that is Using CORS.

When you are using postman they are not restricted by this policy. Quoted from Cross-Origin XMLHttpRequest:

Regular web pages can use the XMLHttpRequest object to send and receive data from remote servers, but they’re limited by the same origin policy. Extensions aren’t so limited. An extension can talk to remote servers outside of its origin, as long as it first requests cross-origin permissions.

shareedit
shareedit

For C# web services – webapi

Please add the following code in your web.config file under <system.webServer> tag. This will work.

<httpProtocol>
    <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
    </customHeaders>
</httpProtocol>

Please make sure you are not doing any mistake in the Ajax call.

jQuery

$.ajax({
    url: 'http://mysite.microsoft.sample.xyz.com/api/mycall',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    type: "POST", /* or type:"GET" or type:"PUT" */
    dataType: "json",
    data: {
    },
    success: function (result) {
        console.log(result);
    },
    error: function () {
        console.log("error");
    }
});

Angular 4 issue, please refer to How to fix Angular 4 API call issues.

shareedit

How to retrieve output parameter from stored procedure in Entity Framework

[Author]: https://code.msdn.microsoft.com/How-to-retrieve-output-e85526ba

How to get output parameter in stored procedure from Entity Framework(CSEFOutputParameter)

Introduction

This sample demonstrates how to use ObjectParameter instance to get the value of output parameter in Entity Framework.

Building the Sample

  1. Start Visual Studio 2012 and select File > Open > Project/Solution.
  2. Go to the directory in which you download the sample. Go to the directory named for   the sample, and double-click the Microsoft Visual Studio Solution (.sln) file.
  3. Attach the database file EFDemoDB.mdf under the folder _External_Dependencies to your SQL Server 2008R2 database instance.
  4. Modify the connection string in the App.config according to your SQL Server 2008R2 database instance name.
  5. Press F7 or use Build > Build Solution to build the sample.

Running the Sample

  1. Right click the solution and built it.
  2. Press F5 to run the project, a console window will appear.

3

3.Follow the prompt to input person information.

Using the Code

Stored Procedure

ALTER PROCEDURE [dbo].[InsertPerson]    
@Name varchar(50),    
@Description varchar(200),      
@ID int OUT    
AS    
INSERT INTO Person(Name,Description) VALUES(@Name,@Description)    
SET @ID = SCOPE_IDENTITY() 

The code below demonstrates how to get the value of output parameter.

// Create a ObjectParameter instance to retrieve output parameter from stored procedure 
ObjectParameter Output = new ObjectParameter("ID", typeof(Int32)); 
context.InsertPerson(Name, Description, Output);   

Console.Write("ID: {0}", Output.Value); 

Model binding JSON POSTs in ASP.NET Core

[Origin]: https://andrewlock.net/model-binding-json-posts-in-asp-net-core/

I was catching up on the latest ASP.NET Community Standup the other day when a question popped up about Model Binding that I hadn’t previously picked up on (you can see the question around 46:30). It pointed out that in ASP.NET Core (the new name for ASP.NET 5), you can no longer simply post JSON data to an MVC controller and have it bound automatically, which you could previously do in ASP.NET 4/MVC 5.

In this post, I am going to show what to do if you are converting a project to ASP.NET Core and you discover your JSON POSTs aren’t working. I’ll demonstrate the differences between MVC 5 model binding and MVC Core model binding, highlighting the differences between the two, and how to setup your controllers for your project, depending on the data you expect.

TL;DR: Add the [FromBody] attribute to the parameter in your ASP.NET Core controller action

Where did my data go?

Imagine you have created a shiny new ASP.NET core project which you are using to rewrite an existing ASP.NET 4 app (only for sensible reasons of course!) You copy and paste your old WebApi controller in to your .NET Core Controller, clean up the namespaces, test out the GET action and all seems to be working well.

Note: In ASP.NET 4, although the MVC and WebApi pipelines behave very similarly, they are completely separate. Therefore you have separate ApiController and Controller classes for WebApi and Mvc respectively (and all the associated namespace confusion). In ASP.NET Core, the pipelines have all been merged and there is only the single Controller class.

As your GET request is working, you know the majority of your pipeline, for example routing, is probably configured correctly. You even submit a test form, which sends a POST to the controller and receives the JSON values it sent back. All looking good.

Posting x-www-url-formencoded content to ASP.NET Core controller

As the final piece of the puzzle, you test sending an AJAX POST with the data as JSON, and it all falls apart – you receive a 200 OK, but all the properties on your object are empty. But why?

Posting JSON content to ASP.NET Core controller

What is Model Binding?

Before we can go into details of what is happening here, we need to have a basic understanding of model binding. Model binding is the process whereby the MVC or WebApi pipeline takes the raw HTTP request and converts that into the arguments for an action method invocation on a controller.

So for example, consider the following WebApi controller and Person class:

public class PersonController : ApiController  
{
    [HttpPost]
    public Person Index(Person person)
    {
        return person;
    }
}

public class Person  
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
}

We can see that there is a single action method on the controller, a POST action, which takes a single parameter – an instance of the Person class. The controller then just echoes that object out, back to the response.

So where does the Person parameter come from? Model binding to the rescue! There are a number of different places the model binders can look for data in order to hydrate the person object. The model binders are highly extensible, and allow custom implementations, but common bindings include:

  • Route values – navigating to a route such as {controller}/{action}/{id} will allow binding to an idparameter
  • Querystrings – If you have passed variables as querystring parameters such as ?FirstName=Andrew, then the FirstName parameter can be bound.
  • Body – If you send data in the body of the post, this can be bound to the Person object
  • Header – You can also bind to HTTP header values, though this is less common.

So you can see there are a number of ways to send data to the server and have the model binder automatically create the correct method parameter for you. Some require explcit configuration, while others you get for free. For example Route values and querystring parameters are always bound, and for complex types (i.e. not primitives like string or int) the body is also bound.

It is important to note that if the model binders fail to bind the parameters for some reason, they will not throw an error, instead you will receive a default object, with none of the properties set, which is the behaviour we showed earlier.

How it works in ASP.NET 4

To play with what’s going on here I created two projects, one using ASP.NET 4 and the other using the latest ASP.NET Core (so very nearly RC2). You can find them on github here and here.

In the ASP.NET WebApi project, there is a simple controller which takes a Person object and simply returns the object back as I showed in the previous section.

On a simple web page, we then make POSTs (using jQuery for convenience), sending requests either x-www-form-urlencoded (as you would get from a normal form POST) or as JSON.

 //form encoded data
 var dataType = 'application/x-www-form-urlencoded; charset=utf-8';
 var data = $('form').serialize();

 //JSON data
 var dataType = 'application/json; charset=utf-8';
 var data = {
    FirstName: 'Andrew',
    LastName: 'Lock',
    Age: 31
 }

 console.log('Submitting form...');
 $.ajax({
    type: 'POST',
    url: '/Person/Index',
    dataType: 'json',
    contentType: dataType,
    data: data,
    success: function(result) {
        console.log('Data received: ');
        console.log(result);
    }
});

This will create an HTTP request for the form encoded POST similar to (elided for brevity):

POST /api/Person/UnProtected HTTP/1.1  
Host: localhost:5000  
Accept: application/json, text/javascript, */*; q=0.01  
Content-Type: application/x-www-form-urlencoded; charset=UTF-8

FirstName=Andrew&amp;LastName=Lock&amp;Age=31  

and for the JSON post:

POST /api/Person/UnProtected HTTP/1.1  
Host: localhost:5000  
Accept: application/json, text/javascript, */*; q=0.01  
Content-Type: application/json; charset=UTF-8

{"FirstName":"Andrew","LastName":"Lock","Age":"31"}

Sending these two POSTs elicits the following console response:

Image of successful posts to ASP.NET 4 controller

In both cases the controller has bound to the body of the HTTP request, and the parameters we sent were returned back to us, without us having to do anything declarative. The model binders do all the magic for us. Note that although I’ve been working with a WebApi controller, the MVC controller model binders behave the same in this example, and would bind both POSTs.

The new way in ASP.NET Core

So, moving on to ASP.NET Core, we create a similar controller, using the same Person class as a parameter as before:

public class PersonController : Controller  
{
    [HttpPost]
    public IActionResult Index(Person person){
        return Json(person);   
    } 
}

Using the same HTTP requests as previously, we see the following console output, where the x-www-url-formencoded POST is bound correctly, but the JSON POST is not.

x-www-url-formencoded post is bound correctly but JSON post is not

In order to bind the JSON correctly in ASP.NET Core, you must modify your action to include the attribute [FromBody] on the parameter. This tells the framework to use the content-type header of the request to decide which of the configured IInputFormatters to use for model binding.

By default, when you call AddMvc() in Startup.cs, a JSON formatterJsonInputFormatter, is automatically configured, but you can add additional formatters if you need to, for example to bind XML to an object.

With that in mind, our new controller looks as follows:

public class PersonController : Controller  
{
    [HttpPost]
    public IActionResult Index([FromBody] Person person){
        return Json(person);   
    } 
}

And our JSON POST now works like magic again!

JSON binding working correctly with FromBody attribute

So just always include [FromBody]?

So if you were thinking you can just always use [FromBody] in your methods, hold your horses. Lets see what happens when you hit your new endpoint with a x-www-url-formencoded request:

Unsupported Media type using x-www-url-formencoded with FromBody attribute

Oh dear. In this case, we have specifically told the ModelBinder to bind the
body of the post, which is FirstName=Andrew&LastName=Lock&Age=31, using an IInputFormatter. Unfortunately, the JSON formatter is the only formatter we have and that doesn’t match our content type, so we get a 415 error response.

In order to specifically bind to the form parameters we can either remove the FromBody attribute or add the alternative FromForm attribute, both of which will allow our form data to be bound but again will prevent the JSON binding correctly.

But what if I need to bind both data types?

In some cases you may need to be able to bind both types of data to an action. In that case, you’re a little bit stuck, as it won’t be possible to have the same end point receive two different sets of data.

Instead you will need to create two different action methods which can specifically bind the data you need to send, and then delegate the processing call to a common method:

public class PersonController : Controller  
{
    //This action at /Person/Index can bind form data 
    [HttpPost]
    public IActionResult Index(Person person){
        return DoSomething(person);   
    } 

    //This action at /Person/IndexFromBody can bind JSON 
    [HttpPost]
    public IActionResult IndexFromBody([FromBody] Person person){
        return DoSomething(person);   
    } 

    private IActionResult DoSomething(Person person){
        // do something with the person here
        // ...

        return Json(person);
    }
}

You may find it inconvenient to have to use two different routes for essentially the same action. Unfortunately, routes are obviously mapped to actions before model binding has occurred, so the model binder cannot be used as a discriminator. If you try to map the two above actions to the same route you will get an error saying Request matched multiple actions resulting in ambiguity. It may be possible to create a custom route to call the appropriate action based on header values, but in all likelihood that will just be more effort than it’s worth!

Why the change?

So why has this all changed? Wasn’t it simpler and easier the old way? Well, maybe, though there are a number of gotchas to watch out for, particularly when POSTing primitive types.

The main reason, according to Damian Edwards at the community standup, is for security reasons, in particular cross-site request forgery (CSRF) prevention. I will do a later post on anti-CSRF in ASP.NET Core, but in essence, when model binding can occur from multiple different sources, as it did in ASP.NET 4, the resulting stack is not secure by default. I confess I haven’t got my head around exactly why that is yet or how it could be exploited, but I presume it is related to identifying your anti-CSRF FormToken when you are getting your data from multiple sources.

Summary

In short, if your model binding isn’t working properly, make sure it’s trying to bind from the right part of your request and you have registered the appropriate formatters. If it’s JSON binding you’re doing, adding [FromBody] to your parameters should do the trick!

References