Laden...

Windows Phone POST an MVC Webservice

Erstellt von Myrana vor 8 Jahren Letzter Beitrag vor 8 Jahren 2.327 Views
M
Myrana Themenstarter:in
18 Beiträge seit 2015
vor 8 Jahren
Windows Phone POST an MVC Webservice

Hallo zusammen,
ich habe einen laufenden MVC Webservice welcher die folgende Create Mehode anbietet:


        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "lo,la,ac")] MarkerDB markerDB)
        {
            if (ModelState.IsValid)
            {
                db.Marker.Add(markerDB);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(markerDB);
        }

Dazu habe ich noch eine Windows Phone App, welche Daten hat die zur Create Methode passen.

Jetzt nur die Frage, wie sende ich Daten an den Webservice...?
Leider finde ich nur Lösungen in denen die Daten Codiert und dann gesendet werden wie hier:


            HttpFormUrlEncodedContent geformteDaten = new HttpFormUrlEncodedContent(daten);

                //Daten senden und Response entgegennehmen
                HttpResponseMessage response = await client.PostAsync(zielserverUri, geformteDaten);

Kennt da einer eine möglichkeit die Daten als Objekt oder wenn nötig auch als JSON Datensatz zu senden?

Vielen Dank im Vorraus!!

2.207 Beiträge seit 2011
vor 8 Jahren
var objectAlsJson = JsonConvert.SerializeObject(myObject);
var content = new StringContent(objectAlsJson , Encoding.UTF8, "application/json");
var result = await _httpClient.PostAsync(uri, content);

HttpClient.PostAsync-Methode (Uri, HttpContent)

S
417 Beiträge seit 2008
vor 8 Jahren

Hi,

das wird so aufgrund des [ValidateAntiForgeryToken]-Attributs nicht funktionieren.
Damit soll ja gerade sichergestellt werden, dass keine Cross-Site requests (in diesem Fall von deiner Windows App heraus) gemacht werden.

2.298 Beiträge seit 2010
vor 8 Jahren

Hallo Myrana,

warum erstellst du nicht einen richtigen ASP.NET Webdienst, der als Schnittstelle für deine Windows Phone Anwendung dient?

Dann kannst du z.B. direkt eine Proxy-Klasse generieren und diese als Schnittstelle verwenden. Ein Umkonvertieren / Codieren der Daten passiert dann automatisch.

Soweit ich das sehe gehört der von dir gepostete Code ja direkt zu einer ASP.NET-Seite. - Das würde ich entkoppelt halten. Die Seite die Daten anzeigt, der allein stehende Webservice der Daten entgegen nimmt und bereitstellt und deine App, die Daten vom Webservice abruft und an diesen sendet.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

16.842 Beiträge seit 2008
vor 8 Jahren

Damit soll ja gerade sichergestellt werden, dass keine Cross-Site requests (in diesem Fall von deiner Windows App heraus) gemacht werden.

Und das deckst Du i.d.R. in der heutigen Zeit mit OAuth2 und Claims ab, bei der Du explizit gewisse Quellen via CORS erlaubst.

M
Myrana Themenstarter:in
18 Beiträge seit 2015
vor 8 Jahren

Vielen Dank für die vielen Antworten!

@inflames2k:
Ich bin noch recht neu in dieser Materie, daher wollte ich es vorerst so einfach und klein wie möglich halten. Oder was meinst du mit einem richtigen ASP.NET Webdienst?

Ich habe die Lösung von Coffebean jetzt implementiert und meinen Webservice angepasst jedoch scheint ncoh immer ein Fehler vorhanden sein. Ich kann zwar den Webservice Ansprechen (Versuch durch REST Client) jedoch passiert nichts..

Webservice:


        //POST: MarkerDB/CreateMarker
        [HttpPost]
        public void CreateMarker(JObject markerJson)
        {            
            MarkerDB marker = markerJson.ToObject<MarkerDB>();
            db.Marker.Add(marker);
            db.SaveChanges();
        }

Windows Phone:


                //Daten in die richtige Form bringen:
                var datenJson = JsonConvert.SerializeObject(daten);
                var content = new StringContent(datenJson, Encoding.UTF8, "application/json");

                //Daten senden und Response entgegennehmen
                var response = await httpClient.PostAsync(uri, content);

16.842 Beiträge seit 2008
vor 8 Jahren
  1. Ein ActionResult sollte niemals void sein (ab MVC 6 leider eher schon)
  2. Sollte eine Action immer einen festen Typ annehmen. Die Umwandlung von Json auf das Modell kann ASP.NET von Haus aus

Und wichtig, was Du eigentlich direkt hättest mit sagen sollen, für die Fehleranalyse: was steht denn in response drin und was bekommt Du für einen HttpCode zurück?
Spätestens daraus solltest Du eigentlich den Fehler selbst entdecken können.

2.298 Beiträge seit 2010
vor 8 Jahren

Vielen Dank für die vielen Antworten!

@inflames2k:
Ich bin noch recht neu in dieser Materie, daher wollte ich es vorerst so einfach und klein wie möglich halten. Oder was meinst du mit einem richtigen ASP.NET Webdienst?

Dazu: Verwenden von ASP.NET Webdiensten

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

M
Myrana Themenstarter:in
18 Beiträge seit 2015
vor 8 Jahren

zu 1) das werde ich noch korrigieren
zu 2) was meinst du damit? Es wird doch ein JObject entgegengenommen oder gibt es da etwas besseres um einen JSON Datensatz anzunehmen?

Fehlermeldung beim Versuch mit dem REST Client:
HTTP Fehler Code: 500 Internal Server Error


<!DOCTYPE html>
<html>
    <head>
        <title>Ungültiger JSON-Primitiv: Id.</title>
        <meta name="viewport" content="width=device-width" />
        <style>
         body {font-family:"Verdana";font-weight:normal;font-size: .7em;color:black;} 
         p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px}
         b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px}
         H1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red }
         H2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon }
         pre {font-family:"Consolas","Lucida Console",Monospace;font-size:11pt;margin:0;padding:0.5em;line-height:14pt}
         .marker {font-weight: bold; color: black;text-decoration: none;}
         .version {color: gray;}
         .error {margin-bottom: 10px;}
         .expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; }
         @media screen and (max-width: 639px) {
          pre { width: 440px; overflow: auto; white-space: pre-wrap; word-wrap: break-word; }
         }
         @media screen and (max-width: 479px) {
          pre { width: 280px; }
         }
        </style>
    </head>

    <body bgcolor="white">

            <span><H1>Serverfehler in der Anwendung /.<hr width=100% size=1 color=silver></H1>

            <h2> <i>Ungültiger JSON-Primitiv: Id.</i> </h2></span>

            <font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">

            <b> Beschreibung: </b>Unbehandelte Ausnahme beim Ausführen der aktuellen Webanforderung. Überprüfen Sie die Stapelüberwachung, um weitere Informationen über diesen Fehler anzuzeigen und festzustellen, wo der Fehler im Code verursacht wurde.

            <br><br>

            <b> Ausnahmedetails: </b>System.ArgumentException: Ungültiger JSON-Primitiv: Id.<br><br>

            <b>Quellfehler:</b> <br><br>

            <table width=100% bgcolor="#ffffcc">
               <tr>
                  <td>
                      <code>

Beim Ausführen der aktuellen Webanforderung wurde einen unbehandelte Ausnahme generiert. Informationen über den Ursprung und die Position der Ausnahme können mit der Ausnahmestapelüberwachung angezeigt werden.</code>

                  </td>
               </tr>
            </table>

            <br>

            <b>Stapelüberwachung:</b> <br><br>

            <table width=100% bgcolor="#ffffcc">
               <tr>
                  <td>
                      <code><pre>

[ArgumentException: Ungültiger JSON-Primitiv: Id.]
   System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializePrimitiveObject() +875
   System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth) +438
   System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(String input, Int32 depthLimit, JavaScriptSerializer serializer) +103
   System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit) +206
   System.Web.Script.Serialization.JavaScriptSerializer.DeserializeObject(String input) +86
   System.Web.Mvc.JsonValueProviderFactory.GetDeserializedObject(ControllerContext controllerContext) +298
   System.Web.Mvc.JsonValueProviderFactory.GetValueProvider(ControllerContext controllerContext) +123
   System.Web.Mvc.ValueProviderFactoryCollection.GetValueProvider(ControllerContext controllerContext) +160
   System.Web.Mvc.ControllerBase.get_ValueProvider() +85
   System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +154
   System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +199
   System.Web.Mvc.Async.&lt;&gt;c__DisplayClass21.&lt;BeginInvokeAction&gt;b__19(AsyncCallback asyncCallback, Object asyncState) +1680
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +59
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
   System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag, Int32 timeout) +94
   System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) +559
   System.Web.Mvc.Controller.&lt;BeginExecuteCore&gt;b__1c(AsyncCallback asyncCallback, Object asyncState, ExecuteCoreState innerState) +82
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +73
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
   System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +105
   System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) +588
   System.Web.Mvc.Controller.&lt;BeginExecute&gt;b__14(AsyncCallback asyncCallback, Object callbackState, Controller controller) +47
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +65
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
   System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +139
   System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +484
   System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +50
   System.Web.Mvc.MvcHandler.&lt;BeginProcessRequest&gt;b__4(AsyncCallback asyncCallback, Object asyncState, ProcessRequestState innerState) +98
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +73
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
   System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +106
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +446
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +88
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +50
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +103
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously) +155
</pre></code>

                  </td>
               </tr>
            </table>

            <br>

            <hr width=100% size=1 color=silver>

            <b>Versionsinformationen:</b>&nbsp;Microsoft .NET Framework-Version:4.0.30319; ASP.NET-Version:4.6.79.0

            </font>

    </body>
</html>
<!-- 
[ArgumentException]: Ungültiger JSON-Primitiv: Id.
   bei System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializePrimitiveObject()
   bei System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)
   bei System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(String input, Int32 depthLimit, JavaScriptSerializer serializer)
   bei System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit)
   bei System.Web.Script.Serialization.JavaScriptSerializer.DeserializeObject(String input)
   bei System.Web.Mvc.JsonValueProviderFactory.GetDeserializedObject(ControllerContext controllerContext)
   bei System.Web.Mvc.JsonValueProviderFactory.GetValueProvider(ControllerContext controllerContext)
   bei System.Web.Mvc.ValueProviderFactoryCollection.GetValueProvider(ControllerContext controllerContext)
   bei System.Web.Mvc.ControllerBase.get_ValueProvider()
   bei System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor)
   bei System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
   bei System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__19(AsyncCallback asyncCallback, Object asyncState)
   bei System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallBeginDelegate(AsyncCallback callback, Object callbackState)
   bei System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout)
   bei System.Web.Mvc.Async.AsyncResultWrapper.Begin[TResult](AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag, Int32 timeout)
   bei System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state)
   bei System.Web.Mvc.Controller.<BeginExecuteCore>b__1c(AsyncCallback asyncCallback, Object asyncState, ExecuteCoreState innerState)
   bei System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState)
   bei System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout)
   bei System.Web.Mvc.Async.AsyncResultWrapper.Begin[TState](AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext)
   bei System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state)
   bei System.Web.Mvc.Controller.<BeginExecute>b__14(AsyncCallback asyncCallback, Object callbackState, Controller controller)
   bei System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState)
   bei System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout)
   bei System.Web.Mvc.Async.AsyncResultWrapper.Begin[TState](AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext)
   bei System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state)
   bei System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state)
   bei System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__4(AsyncCallback asyncCallback, Object asyncState, ProcessRequestState innerState)
   bei System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState)
   bei System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout)
   bei System.Web.Mvc.Async.AsyncResultWrapper.Begin[TState](AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext)
   bei System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state)
   bei System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state)
   bei System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
   bei System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   bei System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
-->

16.842 Beiträge seit 2008
vor 8 Jahren

Na, da haste Deinen Fehler doch: ungültiges Json Primitiv.
Zeig mal MarkerDB; da ist was drin, was mit Json nicht serialisierbar ist.

M
Myrana Themenstarter:in
18 Beiträge seit 2015
vor 8 Jahren

    public class MarkerDB
    {
        public int Id { get; set; }
        public string longitude { get; set; }
        public string latitude { get; set; }
        public string accuracy { get; set; }
    }

hmm ist aber eig. nichts weltbewegendes..

16.842 Beiträge seit 2008
vor 8 Jahren

Und der nächste Schritt für Dich wäre, dass Du überprüfst, ob das Json, das erstellt wird, gültig ist.

M
Myrana Themenstarter:in
18 Beiträge seit 2015
vor 8 Jahren

Ok ich hab das Problem gefunden..
Es lag an meinem Router der lediglich einen Parameter entgegengenommen hat.


            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );

Jetzt stehe ich somit vor einem neuen Problem. Und zwar ob es eine möglichkeit gibt json daten im content anzunehmen.

Kann man das irgendwie im RouteConfig einstellen?

S
417 Beiträge seit 2008
vor 8 Jahren

Das geht mittels [FromBody]-Attribut und hat mit dem Routing nichts zu tun.

public IActionResult ControllerMethod([FromBody]DeinModel model)
{ ... }
M
Myrana Themenstarter:in
18 Beiträge seit 2015
vor 8 Jahren

Ah da habe ich micht vertan..
Aber jetzt funktioniert alles!!

Vielen Dank an alle!!!