Xamarin.Forms HttpClient to RESTful webservice - ios

I have a Xamarin.Forms PCL application that access webservices via HttpClient. The app is working on Android but on iOS it doesn't connect to the webservices at all. Do I need to create a proxy for iOS and REST?
I have read the information here http://developer.xamarin.com/guides/cross-platform/application_fundamentals/web_services/ but frankly, it just confused me. I tried to create the proxy, as set out but it didn't work. I will persevere if it is necessary though.
I also tried HttpWebRequest method but wasn't successful with that either.

You only need to generate a proxy for WCF or SOAP. Rest should work just fine. This is how I implemented a GET to a REST service using HttpClient in a PCL.
using (var client = new HttpClient())
{
var result = await client.GetStringAsync(url);
return JsonConvert.DeserializeObject<Movie>(result);
}
Of course the other verbs take a little bit more work.
Do you perhaps need a binding redirect in the app.config? Check out this blog post about adding a redirect: http://motzcod.es/post/78863496592/portable-class-libraries-httpclient-so-happy.
Here is an example:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="2.0.5.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

Related

MVC Web API - CORS Policy not working

I have created a simple Web API in our existing MVC application (By adding an API controller). I hosted API to localhost and created an simple html page to call the service and to check CORS. To enable I changed my web.config file with following lines:
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
Everything was working fine and API was accessible through html page to localhost.
With same changes I hosted it on server (shared hosting server). It is throwing the same irritating error
XMLHttpRequest cannot load http://www.mywebsite.com/api/Booking. Invalid HTTP status code 405
According to search on Google it should work with these web.config changes. Please help to resolve the issue.
Thanks
Finally after spending a full day resolved the issue, followed link posted by "Yaser".
But I would say it is not easy that's why I am mentioning steps here.
First of all we need to install package through Nuget "Install-Package Microsoft.AspNet.WebApi.Cors" but if your target framework is 4.0 you cannot install it. First convert into 4.5 by right click on Project => Properties then in application tab select framework 4.5
The another gotcha is most of dll's will not work after changing framework version, again Right click on solution and select on Manage Nuget Package and update all. (take back up your project before doing this)
if everything works fine you are just one step away - add the following line in webapiconfig.cs under app_start folder
config.EnableCors();
After that open you API controller, add following line at controller level
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class BookingController : ApiController
{
}
Last step change your web.config on production server add following line (compare with localhost web.config)
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
All make a new build and replace all the bin files with new one ........ :)
Thanks

Deploy WebSharper 2.4 sitelet on IIS7.5

I created a websharper sitelet project from Visual Studio 2012, which I called SiteletTest.
I compiled this project.
Then I copied SiteletTest/Web to inetpub/wwwroot.
Then I go to localhost/SiteletTest, localhost/SiteletTest/Home and localhost/SiteletTest/home but in each case I get http 404.
If I go to localhost/Main.html then I get a page, so going to this directory seems to work, but websharper doesn't appear to be working.
My web.config is below, and I have no idea what else to do. I already set the application pool to use .net 4:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<authentication mode="Forms" />
<pages>
<controls>
<add tagPrefix="WebSharper" namespace="IntelliFactory.WebSharper.Web" assembly="IntelliFactory.WebSharper.Web" />
<add tagPrefix="ws" namespace="Website" assembly="Website" />
</controls>
</pages>
<httpModules>
<add name="WebSharper.Remoting" type="IntelliFactory.WebSharper.Web.RpcModule, IntelliFactory.WebSharper.Web" />
<add name="WebSharper.Sitelets" type="IntelliFactory.WebSharper.Sitelets.HttpModule, IntelliFactory.WebSharper.Sitelets" />
</httpModules>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules>
<add name="WebSharper.Remoting" type="IntelliFactory.WebSharper.Web.RpcModule, IntelliFactory.WebSharper.Web" />
<add name="WebSharper.Sitelets" type="IntelliFactory.WebSharper.Sitelets.HttpModule, IntelliFactory.WebSharper.Sitelets" />
</modules>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
<assemblyBinding appliesTo="v4.0.30319" xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="2.0.0.0" newVersion="4.3.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
I am not going to be paying for a license until I get an idea if this may work for my needs, so, how do I get this to work?
I don't want to copy the sitelet code, but here are some fragments:
type Action =
| Home
| Contact
| Protected
| Login of option<Action>
| Logout
| Echo of string
and another fragment:
module Pages =
/// The home page.
let HomePage : Content<Action> =
Skin.WithTemplate "Home" <| fun ctx ->
[
H1 [Text "Welcome to our site!"]
"Let us know how we can contact you" => ctx.Link Action.Contact
]
I'm pretty sure you are missing 1 of three things:
1- Your sitelet/router isn't defined... something like this:
type Site() =
interface IWebsite<Action> with
member x.Sitelet =
Sitelet.Infer
<| function
| Home -> Pages.HomePage
...
member x.Actions = []
This maps each of the action cases to the correct page. There are many ways to define it but the above Sitelet.Infer will simply map the route by name.
2- You did not specify a Website assembly attribute... something like this:
[<assembly : Website(typeof<Site>)>]
do ()
I think this tells ASP.NET to load the above Sitelet as your site.
3- A third option is to automatically load a client-side JavaScript control from a Default.aspx page in the C# Web Project. If you use the Web Application (ASP.NET) template, you will see an example of that... but with that I do not think you can control the URL Path in a REST-full manner.

OpenID doesnt work with DotNetOpenAuth after upgrade to ver4

I have just upgraded my DotNetOpenAuth version from 3.4.7.11121 to 4.0.0.12079-RC1 to get support for OAuth2. The problem is that after the upgrade my OpenID-requests not longer works. The last row below generates a FileNotFoundException (Message=Could not load file or assembly 'System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies.)
OpenIdRelyingParty openid = new OpenIdRelyingParty()
var request = openid.CreateRequest(requestedIdentifier, Realm.AutoDetect, returnUrl);
return request.RedirectingResponse.AsActionResult();
I can't really understand why it looks for that file. I use the DotNetOpenAuth library in a MVC3 application, and thus the 3.0-version of the System.Web.Mvc-file exists in the project.
Anyone that has any ideas what I can do to make it work?
Updated: The stable 4.0.0.12084 version was released a few hours after I posted this question. Have installed that instead of the RC, but it doesn't make any difference. I tried to install MVC ver 1.0 in order to get the required dll. After the installation no exception is thrown, but instead a white page containing the text "DotNetOpenAuth.Messaging.OutgoingWebResponseActionResult" is displayed instead of the redirect to the OpenID-service provider. I don't understand this..
//Per Andersson
Yeay, I found a solution. Just add a few lines in web.config
<runtime>
<legacyHMACWarning enabled="0" />
<!-- When targeting ASP.NET MVC 3, this assemblyBinding makes MVC 1 and 2 references relink
to MVC 3 so libraries such as DotNetOpenAuth that compile against MVC 1 will work with it. -->
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>

Microsoft Unit Testing with ASP.NET membership provider

Is anyone else frustrated with the built in ASP.NET unit testing framework? The problem I am having is connecting and testing against the Membership provider for ASP.NET in a MVC3 application. It looks like the database connection has not been established or that there is a different set of rules in place then when I run the application normally. Here are the two scenarios.
1) Attempting to find an existing user by name:
Unit Test -
[TestMethod]
public void RegisterTest()
{
AccountController target = new AccountController();
RegisterModel model = new RegisterModel() { UserName = "existinguser", Email = "email#test.com", Password = "Password", ConfirmPassword = "Password" };
actual = target.Register(model);
}
Code chunk from the AccountController -
MembershipCreateStatus createStatus;
MembershipUserCollection members = Membership.FindUsersByName(model.UserName);
MembershipUser user = null;
if (members.Count > 0)
createStatus = MembershipCreateStatus.DuplicateUserName;
Result -
When I step into this code the members array is empty even though I know this user to be in the system. Is there some trick to establishing a connection to the membership store in the unit testing application? I have attempted using the datasource attribute with no success.
2) Attempting to create a new membership account:
The unit test is the same as above however I am passing a new user that is not already in the system. When I step into the controller and get to the following line it gives me a membershipCreateStatus of 'InvalidQuestion'. This seems odd since when running this live I don't have that problem and can create accounts with the line as it is.
user = Membership.CreateUser(model.UserName, model.Password, model.Email, string.Empty, string.Empty, true, null, out createStatus);
Thanks in advance for your help. I am really trying to do this test first method but it's making it harder using the built in testing framework. Certainly there is a way to connect to the DB for all the unit tests (not providing a connection for each test) and simulate the same actions I would through a browser.
When you run your unit tests it will effectively run as a new application and will therefore use its own config file - in other words not web.config that your MVC app uses. So what I would guess you are missing without more information is an entry in the app.config file in your test project, for the connection string to the database that holds your membership information (you may also be missing app.config).
If you are trying to take a TDD approach you should be writing unit tests and if you need to connect to a database for the unit tests to run, they are probably integration tests rather than unit tests. Because the Membership classes use static methods this makes things difficult. What I would recommend is wrapping the membership functionality up in it's own service with a corresponding interface (IMembershipService for example) which can then be injected by your IoC container. For the purposes of your unit tests, you can then simply mock the IMembershipService interface that you created with no need to connect to your database.
I had the same problem. And yes it looks like my unit tests are more like integration tests but I just needed to test the controllers and speed wasn't a concern at this point in the project. I basically added all the sql memberbership config and connection string from the MVC 3 project's web.config to test project's app.config and the membership provider worked when the unit tests ran. Below is my test project's app.config in it's entiriety.
<?xml version="1.0" encoding="utf-8"?>
<!--
Note: Add entries to the App.config file for configuration settings
that apply only to the Test project.
-->
<configuration>
<appSettings></appSettings>
<connectionStrings>
<add name="ApplicationServices" connectionString="mySqlServer;initial catalog=mySqlMembershipDB;persist security info=True;user id=mySqlUser;password=mySqlPassword;" providerName="System.Data.SqlClient" />
</connectionStrings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.5.0" newVersion="4.0.5.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.web>
<membership defaultProvider="AspNetSqlMembershipProvider">
<providers>
<clear />
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
</membership>
<profile defaultProvider="AspNetSqlProfileProvider">
<providers>
<clear />
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/" />
</providers>
</profile>
<roleManager enabled="false" defaultProvider="AspNetSqlRoleProvider">
<providers>
<clear />
<add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
</providers>
</roleManager>
</system.web>
</configuration>

ActionResult redirect renders using ToString()

Using the following sample: http://www.west-wind.com/Weblog/posts/899303.aspx
The following line...
return req.RedirectingResponse.AsActionResult();
renders the string "DotNetOpenAuth.Messaging.OutgoingWebResponseActionResult".
This is the class being returned as ActionResult in the line as posted. Does anyone know why I get the class name as string instead of a actual redirect?
Thnx in advance!
Could it be that you have multiple versions of MVC in your Bin directory and your web server? It strikes me that if you had multiple assemblies (different versions) of the MVC types like ActionResult loaded into your AppDomain, and the AsActionResult method returned one version and your MVC web app used a different version, that it might just bail out with a ToString. What version of ASP.NET MVC are you running? DotNetOpenAuth's AsActionResult method was compiled against the 1.0 RTM version of the MVC framework. If you're using ASP.NET MVC 2 (included with .NET 4.0), I could see this maybe being a problem.
I believe if you add this snippet to your MVC 2's web.config file, that it will allow you to use the official build of DotNetOpenAuth so you don't have to build your own:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
Another solution, working for me with .Net 3.5 and MVC 2.
Instead of
var authRequest = relyingParty.CreateRequest(....);
....
return authRequest.RedirectingResponse.AsActionResult();
use
var authRequest = relyingParty.CreateRequest(....);
....
authRequest.RedirectToProvider();
Response.End();
return new EmptyResult();

Resources